From a5b662cbe4c813f2fd9c059e6d5e3a2243f8f6ad Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 28 Oct 2021 15:49:26 +0200 Subject: [PATCH 001/180] setup wehooks --- .github/workflows/functions-dev.yml | 58 + webhooks/.firebaserc | 5 - webhooks/firebase.json | 20 +- webhooks/functions/.eslintrc.js | 18 - webhooks/functions/package-lock.json | 5940 +------------------------- webhooks/functions/package.json | 8 +- 6 files changed, 241 insertions(+), 5808 deletions(-) create mode 100644 .github/workflows/functions-dev.yml delete mode 100644 webhooks/.firebaserc delete mode 100644 webhooks/functions/.eslintrc.js diff --git a/.github/workflows/functions-dev.yml b/.github/workflows/functions-dev.yml new file mode 100644 index 00000000..2570e8fa --- /dev/null +++ b/.github/workflows/functions-dev.yml @@ -0,0 +1,58 @@ + +name: functions deploy + +on: + push: + branches: [ develop ] + paths: + - 'webhooks/**' + - '.github/workflows/functions-dev.yml' + +jobs: + deploy: + name: "Deploy Firebase functions" + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [16.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + env: + working-directory: './webhooks/functions' + defaults: + run: + working-directory: './webhooks/functions' + + steps: + - name: Checkout repo + uses: actions/checkout@v2 + + - name : GITHUB CONTEXT + env: + GITHUB_CONTEXT: ${{ toJson(github) }} + run: echo "$GITHUB_CONTEXT" + + - name: Install node ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + + - name: Install Dependencies + run: npm ci --no-audit + working-directory: ${{ env.working-directory }} + + - name: set commit name to function config + uses: w9jds/firebase-action@master + with: + args: functions:config:set debug.message=\"${{ github.event.head_commit.message }}\" + env: + FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} + PROJECT_PATH: './webhooks' + + - name: Deploy to Firebase + uses: w9jds/firebase-action@master + with: + args: deploy --only \"functions:ActionsOnGoogleFulfillment\" --project valentin-5 --message \"${{ github.event.head_commit.message }}\" + env: + FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} + PROJECT_PATH: './webhooks' diff --git a/webhooks/.firebaserc b/webhooks/.firebaserc deleted file mode 100644 index 6d5da75c..00000000 --- a/webhooks/.firebaserc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "projects": { - "default": "valentin-4" - } -} diff --git a/webhooks/firebase.json b/webhooks/firebase.json index ffde5d9f..0967ef42 100644 --- a/webhooks/firebase.json +++ b/webhooks/firebase.json @@ -1,19 +1 @@ -{ - "functions": { - "predeploy": [ - "npm --prefix \"$RESOURCE_DIR\" run lint" - ], - "source": "functions" - }, - "emulators": { - "functions": { - "port": 5001 - }, - "firestore": { - "port": 8080 - }, - "ui": { - "enabled": true - } - } -} +{} diff --git a/webhooks/functions/.eslintrc.js b/webhooks/functions/.eslintrc.js deleted file mode 100644 index e5639392..00000000 --- a/webhooks/functions/.eslintrc.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = { - root: true, - env: { - es6: true, - node: true, - }, - "parserOptions": { - "ecmaVersion": 2017 - }, - extends: [ - "eslint:recommended", - // "google", - ], - rules: { - quotes: ["error", "double"], - "no-unused-vars": "off" - }, -}; diff --git a/webhooks/functions/package-lock.json b/webhooks/functions/package-lock.json index a1593347..4901e0a5 100644 --- a/webhooks/functions/package-lock.json +++ b/webhooks/functions/package-lock.json @@ -1,4612 +1,7 @@ { "name": "functions", - "lockfileVersion": 2, "requires": true, - "packages": { - "": { - "name": "functions", - "dependencies": { - "@assistant/conversation": "^3.0.0", - "firebase-admin": "^9.11.1", - "firebase-functions": "^3.14.1", - "opds-fetcher-parser": "github:panaC/opds_fetcher_parser#efec695f50b386071ccf935396f0a8ea4750c9ae" - }, - "devDependencies": { - "eslint": "^7.6.0", - "eslint-config-google": "^0.14.0", - "firebase-functions-test": "^0.2.0" - }, - "engines": { - "node": ">14", - "npm": ">6" - } - }, - "node_modules/@assistant/conversation": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@assistant/conversation/-/conversation-3.8.1.tgz", - "integrity": "sha512-YEyQ33xD1VCkJP16GRdXiuG55Vklbds3yiPcGSSf0hj2dj7mprWybipEZvVA4qsgv/NHrLvXPBFTySJrUpV/7g==", - "dependencies": { - "@types/aws-lambda": "^0.0.33", - "@types/debug": "^0.0.30", - "@types/express": "^4.11.1", - "@types/node": "12.12.24", - "debug": "^3.1.0", - "google-auth-library": "^6.1.0" - }, - "engines": { - "node": ">=10.18.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@eslint/eslintrc/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@eslint/eslintrc/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/@firebase/app": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.7.1.tgz", - "integrity": "sha512-B4z6E1EPQc0mOjF35IPKdDRCFnT/fNQIHfM+v7F9obB7ItPhGILK3LxaQfuampSQpF6GG6TPFDbrWK6myXAq+g==", - "peer": true, - "dependencies": { - "@firebase/component": "0.5.7", - "@firebase/logger": "0.3.0", - "@firebase/util": "1.4.0", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/app-compat": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.1.2.tgz", - "integrity": "sha512-kF1maoqA8bZqJ4v/ojVvA7kIyyXEPkJmL48otGrC8LIgdcen7xCx3JFDe0DGeQywg+qujvdkJz/TptFN1cvAgw==", - "peer": true, - "dependencies": { - "@firebase/app": "0.7.1", - "@firebase/component": "0.5.7", - "@firebase/logger": "0.3.0", - "@firebase/util": "1.4.0", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/app-types": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.7.0.tgz", - "integrity": "sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg==" - }, - "node_modules/@firebase/auth-interop-types": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz", - "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==", - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" - } - }, - "node_modules/@firebase/component": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.7.tgz", - "integrity": "sha512-CiAHUPXh2hn/lpzMShNmfAxHNQhKQwmQUJSYMPCjf2bCCt4Z2vLGpS+UWEuNFm9Zf8LNmkS+Z+U/s4Obi5carg==", - "dependencies": { - "@firebase/util": "1.4.0", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/database": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.12.1.tgz", - "integrity": "sha512-Ethk0hc476qnkSKNBa+8Yc7iM8AO69HYWsaD+QUC983FZtnuMyNLHtEeSUbLQYvyHo7cOjcc52slop14WmfZeQ==", - "dependencies": { - "@firebase/auth-interop-types": "0.1.6", - "@firebase/component": "0.5.7", - "@firebase/logger": "0.3.0", - "@firebase/util": "1.4.0", - "faye-websocket": "0.11.4", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/database-compat": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.1.1.tgz", - "integrity": "sha512-K3DFWiw0YkLZtlfA9TOGPw6zVXKu5dQ1XqIGztUufFVRYW8IizReXVxzSSmJNR4Adr2LiU9j66Wenc6e5UfwaQ==", - "dependencies": { - "@firebase/component": "0.5.7", - "@firebase/database": "0.12.1", - "@firebase/database-types": "0.9.1", - "@firebase/logger": "0.3.0", - "@firebase/util": "1.4.0", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/database-compat/node_modules/@firebase/database-types": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.9.1.tgz", - "integrity": "sha512-RUixK/YrbpxbfdE+nYP0wMcEsz1xPTnafP0q3UlSS/+fW744OITKtR1J0cMRaXbvY7EH0wUVTNVkrtgxYY8IgQ==", - "dependencies": { - "@firebase/app-types": "0.7.0", - "@firebase/util": "1.4.0" - } - }, - "node_modules/@firebase/database-types": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.7.3.tgz", - "integrity": "sha512-dSOJmhKQ0nL8O4EQMRNGpSExWCXeHtH57gGg0BfNAdWcKhC8/4Y+qfKLfWXzyHvrSecpLmO0SmAi/iK2D5fp5A==", - "dependencies": { - "@firebase/app-types": "0.6.3" - } - }, - "node_modules/@firebase/database-types/node_modules/@firebase/app-types": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.6.3.tgz", - "integrity": "sha512-/M13DPPati7FQHEQ9Minjk1HGLm/4K4gs9bR4rzLCWJg64yGtVC0zNg9gDpkw9yc2cvol/mNFxqTtd4geGrwdw==" - }, - "node_modules/@firebase/logger": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.3.0.tgz", - "integrity": "sha512-7oQ+TctqekfgZImWkKuda50JZfkmAKMgh5qY4aR4pwRyqZXuJXN1H/BKkHvN1y0S4XWtF0f/wiCLKHhyi1ppPA==", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/util": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.4.0.tgz", - "integrity": "sha512-Qn58d+DVi1nGn0bA9RV89zkz0zcbt6aUcRdyiuub/SuEvjKYstWmHcHwh1C0qmE1wPf9a3a+AuaRtduaGaRT7A==", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/@google-cloud/common": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.7.2.tgz", - "integrity": "sha512-5Q9f74IbZaY6xAwJSNFy5SrGwbm1j7mpv+6A/r+K2dymjsXBH5UauB0tziaMwWoVVaMq1IQnZF9lgtfqqvxcUg==", - "optional": true, - "dependencies": { - "@google-cloud/projectify": "^2.0.0", - "@google-cloud/promisify": "^2.0.0", - "arrify": "^2.0.1", - "duplexify": "^4.1.1", - "ent": "^2.2.0", - "extend": "^3.0.2", - "google-auth-library": "^7.0.2", - "retry-request": "^4.2.2", - "teeny-request": "^7.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@google-cloud/common/node_modules/google-auth-library": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.10.0.tgz", - "integrity": "sha512-ICsqaU+lxMHVlDUzMrfVIEqnARw2AwBiZ/2KnNM6BcTf9Nott+Af87DTIzmlnW865p3REUP2MVL0xkPC3a61aQ==", - "optional": true, - "dependencies": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@google-cloud/firestore": { - "version": "4.15.1", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.15.1.tgz", - "integrity": "sha512-2PWsCkEF1W02QbghSeRsNdYKN1qavrHBP3m72gPDMHQSYrGULOaTi7fSJquQmAtc4iPVB2/x6h80rdLHTATQtA==", - "optional": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "functional-red-black-tree": "^1.0.1", - "google-gax": "^2.24.1", - "protobufjs": "^6.8.6" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@google-cloud/paginator": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.6.tgz", - "integrity": "sha512-XCTm/GfQIlc1ZxpNtTSs/mnZxC2cePNhxU3X8EzHXKIJ2JFncmJj2Fcd2IP+gbmZaSZnY0juFxbUCkIeuu/2eQ==", - "optional": true, - "dependencies": { - "arrify": "^2.0.0", - "extend": "^3.0.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@google-cloud/projectify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.1.1.tgz", - "integrity": "sha512-+rssMZHnlh0twl122gXY4/aCrk0G1acBqkHFfYddtsqpYXGxA29nj9V5V9SfC+GyOG00l650f6lG9KL+EpFEWQ==", - "optional": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@google-cloud/promisify": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.4.tgz", - "integrity": "sha512-j8yRSSqswWi1QqUGKVEKOG03Q7qOoZP6/h2zN2YO+F5h2+DHU0bSrHCK9Y7lo2DI9fBd8qGAw795sf+3Jva4yA==", - "optional": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@google-cloud/storage": { - "version": "5.14.4", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.14.4.tgz", - "integrity": "sha512-CjpGuk+ZZB7b3yMXPQrPb0TMIhXqbDzrGxngeSl2S2fItFp2pZDnYhvFuB0/8S73cA2T/4x3g1tl6PB1OuuaoQ==", - "optional": true, - "dependencies": { - "@google-cloud/common": "^3.7.0", - "@google-cloud/paginator": "^3.0.0", - "@google-cloud/promisify": "^2.0.0", - "arrify": "^2.0.0", - "async-retry": "^1.3.1", - "compressible": "^2.0.12", - "date-and-time": "^2.0.0", - "duplexify": "^4.0.0", - "extend": "^3.0.2", - "gcs-resumable-upload": "^3.3.0", - "get-stream": "^6.0.0", - "hash-stream-validation": "^0.2.2", - "mime": "^2.2.0", - "mime-types": "^2.0.8", - "p-limit": "^3.0.1", - "pumpify": "^2.0.0", - "snakeize": "^0.1.0", - "stream-events": "^1.0.1", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@grpc/grpc-js": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.7.tgz", - "integrity": "sha512-CKQVuwuSPh40tgOkR7c0ZisxYRiN05PcKPW72mQL5y++qd7CwBRoaJZvU5xfXnCJDFBmS3qZGQ71Frx6Ofo2XA==", - "optional": true, - "dependencies": { - "@types/node": ">=12.12.47" - }, - "engines": { - "node": "^8.13.0 || >=10.10.0" - } - }, - "node_modules/@grpc/grpc-js/node_modules/@types/node": { - "version": "16.10.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.2.tgz", - "integrity": "sha512-zCclL4/rx+W5SQTzFs9wyvvyCwoK9QtBpratqz2IYJ3O8Umrn0m3nsTv0wQBk9sRGpvUe9CwPDrQFB10f1FIjQ==", - "optional": true - }, - "node_modules/@grpc/proto-loader": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.5.tgz", - "integrity": "sha512-GZdzyVQI1Bln/kCzIYgTKu+rQJ5dno0gVrfmLe4jqQu7T2e7svSwJzpCBqVU5hhBSJP3peuPjOMWsj5GR61YmQ==", - "optional": true, - "dependencies": { - "@types/long": "^4.0.1", - "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", - "protobufjs": "^6.10.0", - "yargs": "^16.1.1" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", - "dev": true - }, - "node_modules/@panva/asn1.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", - "integrity": "sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=", - "optional": true - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "optional": true - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "optional": true - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=", - "optional": true - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "optional": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=", - "optional": true - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=", - "optional": true - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=", - "optional": true - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=", - "optional": true - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", - "optional": true - }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "optional": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@types/aws-lambda": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-0.0.33.tgz", - "integrity": "sha512-p13MzAb/1ZJK1h0jDhRjdFqlRHC44HAOS7qYuVpn7NnFDv8UdNbRjExfhK69syvI9IoIR4NN4dRGjpVDsN6tEQ==" - }, - "node_modules/@types/body-parser": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz", - "integrity": "sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/cors": { - "version": "2.8.12", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", - "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" - }, - "node_modules/@types/debug": { - "version": "0.0.30", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-0.0.30.tgz", - "integrity": "sha512-orGL5LXERPYsLov6CWs3Fh6203+dXzJkR7OnddIr2514Hsecwc8xRpzCapshBbKFImCsvS/mk6+FWiN5LyZJAQ==" - }, - "node_modules/@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-jwt": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@types/express-jwt/-/express-jwt-0.0.42.tgz", - "integrity": "sha512-WszgUddvM1t5dPpJ3LhWNH8kfNN8GPIBrAGxgIYXVCEGx6Bx4A036aAuf/r5WH9DIEdlmp7gHOYvSM6U87B0ag==", - "dependencies": { - "@types/express": "*", - "@types/express-unless": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.24", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.24.tgz", - "integrity": "sha512-3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "node_modules/@types/express-unless": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.2.tgz", - "integrity": "sha512-Q74UyYRX/zIgl1HSp9tUX2PlG8glkVm+59r7aK4KGKzC5jqKIOX6rrVLRQrzpZUQ84VukHtRoeAuon2nIssHPQ==", - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/lodash": { - "version": "4.14.175", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.175.tgz", - "integrity": "sha512-XmdEOrKQ8a1Y/yxQFOMbC47G/V2VDO1GvMRnl4O75M4GW/abC5tnfzadQYkqEveqRM1dEJGFFegfPNA2vvx2iw==", - "dev": true - }, - "node_modules/@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==", - "optional": true - }, - "node_modules/@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" - }, - "node_modules/@types/node": { - "version": "12.12.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.24.tgz", - "integrity": "sha512-1Ciqv9pqwVtW6FsIUKSZNB82E5Cu1I2bBTj1xuIHXLe/1zYLl3956Nbhg2MzSYHVfl9/rmanjbQIb7LibfCnug==" - }, - "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" - }, - "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" - }, - "node_modules/@types/serve-static": { - "version": "1.13.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", - "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/xmldom": { - "version": "0.1.31", - "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.31.tgz", - "integrity": "sha512-bVy7s0nvaR5D1mT1a8ZkByHWNOGb6Vn4yi5TWhEdmyKlAG+08SA7Md6+jH+tYmMLueAwNeWvHHpeKrr6S4c4BA==" - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/agent-base/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/agent-base/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "devOptional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "devOptional": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "engines": { - "node": ">=8" - } - }, - "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/async-retry": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", - "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", - "optional": true, - "dependencies": { - "retry": "0.13.1" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/big-integer": { - "version": "1.6.49", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.49.tgz", - "integrity": "sha512-KJ7VhqH+f/BOt9a3yMwJNmcZjG53ijWMTjSAGMveQWyLwqIiwkjNP5PFgDob3Snnx86SjDj6I89fIbv0dkQeNw==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", - "engines": { - "node": "*" - } - }, - "node_modules/binary": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", - "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", - "dependencies": { - "buffers": "~0.1.1", - "chainsaw": "~0.1.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "node_modules/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "dependencies": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "engines": { - "node": "*" - } - }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "node_modules/buffer-indexof-polyfill": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", - "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/buffers": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", - "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", - "engines": { - "node": ">=0.2.0" - } - }, - "node_modules/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "node_modules/chainsaw": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", - "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", - "dependencies": { - "traverse": ">=0.3.0 <0.4" - }, - "engines": { - "node": "*" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "optional": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "devOptional": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "devOptional": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "optional": true, - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "optional": true, - "dependencies": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "dependencies": { - "safe-buffer": "5.1.2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/date-and-time": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-2.0.0.tgz", - "integrity": "sha512-HJSzj25iPm8E01nt+rSmCIlwjsmjvKfUivG/kXBglpymcHF1FolWAqWwTEV4FvN1Lx5UjPf0J1W4H8yQsVBfFg==", - "optional": true - }, - "node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "node_modules/dicer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", - "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", - "dependencies": { - "streamsearch": "0.1.2" - }, - "engines": { - "node": ">=4.5.0" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "optional": true, - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dependencies": { - "readable-stream": "^2.0.2" - } - }, - "node_modules/duplexer2/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/duplexer2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "optional": true, - "dependencies": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "devOptional": true - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "optional": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", - "optional": true - }, - "node_modules/err-code": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", - "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=" - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "optional": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-google": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", - "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "eslint": ">=5.16.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/eslint/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "dependencies": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "node_modules/fast-text-encoding": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", - "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==" - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/fetch-cookie": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-1.0.0.tgz", - "integrity": "sha512-SWcAhkDe4yVBFtwRqJNmot6k1XjjzI7tw3aRHepxXrK6FQp6obBhqcnsdm2aNUzrtE71607crNAYodtKMq3TjA==", - "dependencies": { - "tough-cookie": "^2.3.3 || ^3.0.1 || ^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/file-js": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/file-js/-/file-js-0.3.0.tgz", - "integrity": "sha1-+rRr94I0bJKUSZ8fDSrQfYOPJdE=", - "dependencies": { - "bluebird": "^3.4.7", - "minimatch": "^3.0.3", - "proper-lockfile": "^1.2.0" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "node_modules/filehound": { - "version": "1.17.5", - "resolved": "https://registry.npmjs.org/filehound/-/filehound-1.17.5.tgz", - "integrity": "sha512-BsNTM3xoscYKgv0quE9RWPVhu5ZTb7BNu3H/IbZQbOfQeA7ZyOV/hIYfo60H3Jhorw/J5vbg59KHS1UCHt4FAw==", - "dependencies": { - "bluebird": "^3.7.2", - "file-js": "0.3.0", - "lodash": "^4.17.21", - "minimatch": "^3.0.4", - "moment": "^2.29.1", - "unit-compare": "^1.0.1" - } - }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/firebase-admin": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.12.0.tgz", - "integrity": "sha512-AtA7OH5RbIFGoc0gZOQgaYC6cdjdhZv4w3XgWoupkPKO1HY+0GzixOuXDa75kFeoVyhIyo4PkLg/GAC1dC1P6w==", - "dependencies": { - "@firebase/database-compat": "^0.1.1", - "@firebase/database-types": "^0.7.2", - "@types/node": ">=12.12.47", - "dicer": "^0.3.0", - "jsonwebtoken": "^8.5.1", - "jwks-rsa": "^2.0.2", - "node-forge": "^0.10.0" - }, - "engines": { - "node": ">=10.13.0" - }, - "optionalDependencies": { - "@google-cloud/firestore": "^4.5.0", - "@google-cloud/storage": "^5.3.0" - } - }, - "node_modules/firebase-admin/node_modules/@types/node": { - "version": "16.10.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.2.tgz", - "integrity": "sha512-zCclL4/rx+W5SQTzFs9wyvvyCwoK9QtBpratqz2IYJ3O8Umrn0m3nsTv0wQBk9sRGpvUe9CwPDrQFB10f1FIjQ==" - }, - "node_modules/firebase-functions": { - "version": "3.15.7", - "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.15.7.tgz", - "integrity": "sha512-ZD7r8eoWWebgs+mTqfH8NLUT2C0f7/cyAvIA1RSUdBVQZN7MBBt3oSlN/rL3e+m6tdlJz6YbQ3hrOKOGjOVYvQ==", - "dependencies": { - "@types/cors": "^2.8.5", - "@types/express": "4.17.3", - "cors": "^2.8.5", - "express": "^4.17.1", - "lodash": "^4.17.14" - }, - "engines": { - "node": "^8.13.0 || >=10.10.0" - }, - "peerDependencies": { - "firebase-admin": "^8.0.0 || ^9.0.0" - } - }, - "node_modules/firebase-functions-test": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/firebase-functions-test/-/firebase-functions-test-0.2.3.tgz", - "integrity": "sha512-zYX0QTm53wCazuej7O0xqbHl90r/v1PTXt/hwa0jo1YF8nDM+iBKnLDlkIoW66MDd0R6aGg4BvKzTTdJpvigUA==", - "dev": true, - "dependencies": { - "@types/lodash": "^4.14.104", - "lodash": "^4.17.5" - }, - "engines": { - "node": ">=8.0.0" - }, - "peerDependencies": { - "firebase-admin": ">=6.0.0", - "firebase-functions": ">=2.0.0" - } - }, - "node_modules/firebase-functions/node_modules/@types/express": { - "version": "4.17.3", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.3.tgz", - "integrity": "sha512-I8cGRJj3pyOLs/HndoP+25vOqhqWkAZsWMEmq1qXy/b/M3ppufecUwaK2/TVDVxcV61/iSdhykUjQQ2DLSrTdg==", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "*", - "@types/serve-static": "*" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", - "dev": true - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", - "dependencies": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - }, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/fstream/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "devOptional": true - }, - "node_modules/gaxios": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.2.tgz", - "integrity": "sha512-T+ap6GM6UZ0c4E6yb1y/hy2UB6hTrqhglp3XfmU9qbLCGRYhLVV5aRPpC4EmoG8N8zOnkYCgoBz+ScvGAARY6Q==", - "dependencies": { - "abort-controller": "^3.0.0", - "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/gcp-metadata": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.1.tgz", - "integrity": "sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==", - "dependencies": { - "gaxios": "^4.0.0", - "json-bigint": "^1.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/gcs-resumable-upload": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/gcs-resumable-upload/-/gcs-resumable-upload-3.3.1.tgz", - "integrity": "sha512-WyC0i4VkslIdrdmeM5PNuGzANALLXTG5RoHb08OE30gYT+FEvCDPiA8KOjV2s1wOu9ngEW4+IuzBjtP/ni7UdQ==", - "optional": true, - "dependencies": { - "abort-controller": "^3.0.0", - "configstore": "^5.0.0", - "extend": "^3.0.2", - "gaxios": "^4.0.0", - "google-auth-library": "^7.0.0", - "pumpify": "^2.0.0", - "stream-events": "^1.0.4" - }, - "bin": { - "gcs-upload": "build/src/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/gcs-resumable-upload/node_modules/google-auth-library": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.10.0.tgz", - "integrity": "sha512-ICsqaU+lxMHVlDUzMrfVIEqnARw2AwBiZ/2KnNM6BcTf9Nott+Af87DTIzmlnW865p3REUP2MVL0xkPC3a61aQ==", - "optional": true, - "dependencies": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "optional": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "optional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dependencies": { - "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" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/google-auth-library": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.6.tgz", - "integrity": "sha512-Q+ZjUEvLQj/lrVHF/IQwRo6p3s8Nc44Zk/DALsN+ac3T4HY/g/3rrufkgtl+nZ1TW7DNAw5cTChdVp4apUXVgQ==", - "dependencies": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/google-gax": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.26.0.tgz", - "integrity": "sha512-D/8fjTydl9p3ejxuW3ZVHVZqKzz6zYaz5MMEucijsJonJ4RHqWAzHFKZMKSc7yyUiTEBGqG7nU2S8NUPUUYDEA==", - "optional": true, - "dependencies": { - "@grpc/grpc-js": "~1.3.0", - "@grpc/proto-loader": "^0.6.1", - "@types/long": "^4.0.0", - "abort-controller": "^3.0.0", - "duplexify": "^4.0.0", - "fast-text-encoding": "^1.0.3", - "google-auth-library": "^7.6.1", - "is-stream-ended": "^0.1.4", - "node-fetch": "^2.6.1", - "object-hash": "^2.1.1", - "proto3-json-serializer": "^0.1.1", - "protobufjs": "6.11.2", - "retry-request": "^4.0.0" - }, - "bin": { - "compileProtos": "build/tools/compileProtos.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/google-gax/node_modules/google-auth-library": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.10.0.tgz", - "integrity": "sha512-ICsqaU+lxMHVlDUzMrfVIEqnARw2AwBiZ/2KnNM6BcTf9Nott+Af87DTIzmlnW865p3REUP2MVL0xkPC3a61aQ==", - "optional": true, - "dependencies": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/google-p12-pem": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.2.tgz", - "integrity": "sha512-tjf3IQIt7tWCDsa0ofDQ1qqSCNzahXDxdAGJDbruWqu3eCg5CKLYKN+hi0s6lfvzYZ1GDVr+oDF9OOWlDSdf0A==", - "dependencies": { - "node-forge": "^0.10.0" - }, - "bin": { - "gp12-pem": "build/src/bin/gp12-pem.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" - }, - "node_modules/gtoken": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.3.1.tgz", - "integrity": "sha512-yqOREjzLHcbzz1UrQoxhBtpk8KjrVhuqPE7od1K2uhyxG2BHjKZetlbLw/SPZak/QqTIQW+addS+EcjqQsZbwQ==", - "dependencies": { - "gaxios": "^4.0.0", - "google-p12-pem": "^3.0.3", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/hash-stream-validation": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.4.tgz", - "integrity": "sha512-Gjzu0Xn7IagXVkSu9cSFuK1fqzwtLwFhNhVL8IFJijRNMgUttFbBSIAzKuSIrsFMO1+g1RlsoN49zPIbwPDMGQ==", - "optional": true - }, - "node_modules/http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/http-errors/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "node_modules/http-parser-js": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", - "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==" - }, - "node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "optional": true, - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/http-proxy-agent/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "optional": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/http-proxy-agent/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "optional": true - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/https-proxy-agent/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/https-proxy-agent/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/image-size": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.0.tgz", - "integrity": "sha512-JLJ6OwBfO1KcA+TvJT+v8gbE6iWbj24LyDNFgFEN0lzegn6cC6a/p3NIDaepMsJjQjlUWqIC7wJv8lBFxPNjcw==", - "dependencies": { - "queue": "6.0.2" - }, - "bin": { - "image-size": "bin/image-size.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "devOptional": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "devOptional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-stream-ended": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", - "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==", - "optional": true - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "node_modules/jose": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.5.tgz", - "integrity": "sha512-BAiDNeDKTMgk4tvD0BbxJ8xHEHBZgpeRZ1zGPPsitSyMgjoMWiLGYAE7H7NpP5h0lPppQajQs871E8NHUrzVPA==", - "dependencies": { - "@panva/asn1.js": "^1.0.0" - }, - "engines": { - "node": ">=10.13.0 < 13 || >=13.7.0" - }, - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "node_modules/json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "dependencies": { - "bignumber.js": "^9.0.0" - } - }, - "node_modules/json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "node_modules/jsonwebtoken": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", - "dependencies": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=4", - "npm": ">=1.4.28" - } - }, - "node_modules/jsonwebtoken/node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jsonwebtoken/node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "dependencies": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jsonwebtoken/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "node_modules/jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jwks-rsa": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.0.4.tgz", - "integrity": "sha512-iJqVCECYZZ+3oPmY1qXv3Fq+3ywDtuNEVBvG41pPlaR0zyGxa12nC0beAOBBUhETJmc05puS50mRQN4NkCGhmg==", - "dependencies": { - "@types/express-jwt": "0.0.42", - "debug": "^4.3.2", - "jose": "^2.0.5", - "limiter": "^1.1.5", - "lru-memoizer": "^2.1.4" - }, - "engines": { - "node": ">=10 < 13 || >=14" - } - }, - "node_modules/jwks-rsa/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/jwks-rsa/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "dependencies": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/limiter": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", - "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" - }, - "node_modules/listenercount": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", - "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=" - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", - "optional": true - }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" - }, - "node_modules/lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" - }, - "node_modules/lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" - }, - "node_modules/lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" - }, - "node_modules/lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" - }, - "node_modules/lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true - }, - "node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "optional": true - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/lru-memoizer": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.1.4.tgz", - "integrity": "sha512-IXAq50s4qwrOBrXJklY+KhgZF+5y98PDaNo0gi/v2KQBFLyWr+JyFvijZXkGKjQj/h9c0OwoE+JZbwUXce76hQ==", - "dependencies": { - "lodash.clonedeep": "^4.5.0", - "lru-cache": "~4.0.0" - } - }, - "node_modules/lru-memoizer/node_modules/lru-cache": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", - "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=", - "dependencies": { - "pseudomap": "^1.0.1", - "yallist": "^2.0.0" - } - }, - "node_modules/lru-memoizer/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "optional": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "optional": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", - "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", - "optional": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", - "optional": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.32", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", - "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", - "dependencies": { - "mime-db": "1.49.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types/node_modules/mime-db": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", - "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/nanoid": { - "version": "3.1.28", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.28.tgz", - "integrity": "sha512-gSu9VZ2HtmoKYe/lmyPFES5nknFrHa+/DT9muUFWFMi6Jh9E1I7bkvlQ8xxf1Kos9pi9o8lBnIOkatMhKX/YUw==", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node_modules/negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-fetch": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", - "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - } - }, - "node_modules/node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/node-stream-zip": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.15.0.tgz", - "integrity": "sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw==", - "engines": { - "node": ">=0.12.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/antelle" - } - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "engines": { - "node": "*" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", - "optional": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/opds-fetcher-parser": { - "version": "0.1.0", - "resolved": "git+ssh://git@github.com/panaC/opds_fetcher_parser.git#efec695f50b386071ccf935396f0a8ea4750c9ae", - "integrity": "sha512-vhOHEBu7Bs9y0XHgGo8u6ntgrjAtclGZE61cP11F1HBwBnF8s7w+Vlagc7MJq2xMy0RuMN45lzVoco8Rl9petQ==", - "license": "Apache-2.0", - "dependencies": { - "moment": "^2.29.1", - "nanoid": "^3.1.23", - "r2-lcp-js": "^1.0.30", - "r2-opds-js": "^1.0.35", - "r2-shared-js": "^1.0.51", - "ts-fetch": "github:panaC/ts_fetch#7f585951111aa0e9cb7fe7f99bdd927a9261cd7b" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "optional": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/proper-lockfile": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-1.2.0.tgz", - "integrity": "sha1-zv9d2J0+XxD7deHo52vHWAGlnDQ=", - "dependencies": { - "err-code": "^1.0.0", - "extend": "^3.0.0", - "graceful-fs": "^4.1.2", - "retry": "^0.10.0" - } - }, - "node_modules/proper-lockfile/node_modules/retry": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", - "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", - "engines": { - "node": "*" - } - }, - "node_modules/proto3-json-serializer": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-0.1.4.tgz", - "integrity": "sha512-bFzdsKU/zaTobWrRxRniMZIzzcgKYlmBWL1gAcTXZ2M7TQTGPI0JoYYs6bN7tpWj59ZCfwg7Ii/A2e8BbQGYnQ==", - "optional": true - }, - "node_modules/protobufjs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", - "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, - "node_modules/protobufjs/node_modules/@types/node": { - "version": "16.10.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.2.tgz", - "integrity": "sha512-zCclL4/rx+W5SQTzFs9wyvvyCwoK9QtBpratqz2IYJ3O8Umrn0m3nsTv0wQBk9sRGpvUe9CwPDrQFB10f1FIjQ==", - "optional": true - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "optional": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/pumpify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", - "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", - "optional": true, - "dependencies": { - "duplexify": "^4.1.1", - "inherits": "^2.0.3", - "pump": "^3.0.0" - } - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/queue": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", - "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", - "dependencies": { - "inherits": "~2.0.3" - } - }, - "node_modules/r2-lcp-js": { - "version": "1.0.32", - "resolved": "https://registry.npmjs.org/r2-lcp-js/-/r2-lcp-js-1.0.32.tgz", - "integrity": "sha512-cNpOc9ZWatCe7WPMQxVfA7p1xtynrU7eWZ/Cw41+zkKRUsOU4b+CTtwq1APMut+dMhnEHNIjDVUqxGBnFUa7dw==", - "dependencies": { - "bindings": "^1.5.0", - "debug": "^4.3.2", - "moment": "^2.29.1", - "r2-utils-js": "^1.0.26", - "request": "^2.88.2", - "request-promise-native": "^1.0.9", - "ta-json-x": "^2.5.3", - "tslib": "^2.3.1", - "urijs": "^1.19.7" - }, - "engines": { - "node": ">=12", - "npm": ">=6", - "yarn": ">=1.0" - } - }, - "node_modules/r2-lcp-js/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/r2-lcp-js/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/r2-opds-js": { - "version": "1.0.36", - "resolved": "https://registry.npmjs.org/r2-opds-js/-/r2-opds-js-1.0.36.tgz", - "integrity": "sha512-JQB92qGzJWTO1l8NkZ3AhsQXm197Ny2pnU2NtakjWPnASnw60DJxs14yxXHKjTDZZzLI+XzsWYJJ6BKitIN55w==", - "dependencies": { - "debug": "^4.3.2", - "r2-lcp-js": "^1.0.31", - "r2-shared-js": "^1.0.52", - "r2-utils-js": "^1.0.26", - "ta-json-x": "^2.5.3", - "tslib": "^2.3.1", - "xmldom": "^0.6.0" - }, - "engines": { - "node": ">=6", - "npm": ">=3", - "yarn": ">=1.0" - } - }, - "node_modules/r2-opds-js/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/r2-opds-js/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/r2-shared-js": { - "version": "1.0.52", - "resolved": "https://registry.npmjs.org/r2-shared-js/-/r2-shared-js-1.0.52.tgz", - "integrity": "sha512-GYPdqK7FPUSczC68ZHqz3gFL98VZU/UCQtlgknxvJdDrM7+2Pz805X6iMUMzr1mkL203/Wl8mm+O5BsjQnc8tw==", - "dependencies": { - "debug": "^4.3.2", - "fast-deep-equal": "^3.1.3", - "image-size": "^1.0.0", - "mime-types": "^2.1.32", - "moment": "^2.29.1", - "r2-lcp-js": "^1.0.31", - "r2-utils-js": "^1.0.26", - "slugify": "^1.6.0", - "ta-json-x": "^2.5.3", - "tslib": "^2.3.1", - "xmldom": "^0.6.0", - "xpath": "^0.0.32", - "yazl": "^2.5.1" - }, - "bin": { - "r2-shared-js-cli": "dist/es6-es2015/src/_utils/cli.js" - }, - "engines": { - "node": ">=6", - "npm": ">=3", - "yarn": ">=1.0" - } - }, - "node_modules/r2-shared-js/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/r2-shared-js/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/r2-utils-js": { - "version": "1.0.26", - "resolved": "https://registry.npmjs.org/r2-utils-js/-/r2-utils-js-1.0.26.tgz", - "integrity": "sha512-8t9JIafLP1IXtpCcEqRxSlLtHrGPai3qidAq3Xe3sQTCNv29WZtHPglGSZX95BPPFDhIQfM9CiVvkbgReFFZ4Q==", - "dependencies": { - "@types/xmldom": "^0.1.31", - "debug": "^4.3.2", - "filehound": "^1.17.4", - "node-stream-zip": "^1.14.0", - "reflect-metadata": "^0.1.13", - "request": "^2.88.2", - "request-promise-native": "^1.0.9", - "ta-json-x": "^2.5.3", - "tslib": "^2.3.1", - "unzipper": "^0.10.11", - "xpath": "^0.0.32", - "yauzl": "^2.10.0", - "yazl": "^2.5.1" - }, - "engines": { - "node": ">=6", - "npm": ">=3", - "yarn": ">=1.0" - } - }, - "node_modules/r2-utils-js/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/r2-utils-js/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "optional": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dependencies": { - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", - "dependencies": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "engines": { - "node": ">=0.12.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "optional": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/retry-request": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.2.2.tgz", - "integrity": "sha512-xA93uxUD/rogV7BV59agW/JHPGXeREMWiZc9jhcwY4YdZ7QOtC7qbomYg0n4wyk2lJhggjvKvhNX8wln/Aldhg==", - "optional": true, - "dependencies": { - "debug": "^4.1.1", - "extend": "^3.0.2" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/retry-request/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "optional": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/retry-request/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "optional": true - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dependencies": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/send/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - }, - "node_modules/serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "node_modules/setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "optional": true - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/slugify": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.0.tgz", - "integrity": "sha512-FkMq+MQc5hzYgM86nLuHI98Acwi3p4wX+a5BO9Hhw4JdK4L7WueIiZ4tXEobImPqBz2sVcV0+Mu3GRB30IGang==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/snakeize": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/snakeize/-/snakeize-0.1.0.tgz", - "integrity": "sha1-EMCI2LWOsHazIpu1oE4jLOEmQi0=", - "optional": true - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stream-events": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", - "optional": true, - "dependencies": { - "stubs": "^3.0.0" - } - }, - "node_modules/stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "optional": true - }, - "node_modules/streamsearch": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", - "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "optional": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "optional": true - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "devOptional": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "devOptional": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/stubs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=", - "optional": true - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ta-json-x": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ta-json-x/-/ta-json-x-2.5.3.tgz", - "integrity": "sha512-zhn9oZJVUOj73/WmLFoLszp8+zl8RZAU995dTQWhZK/2eSvFiz2eZ3nN6Kk7B6lRg2GUWnW1v3S3IUhFNbwYQA==", - "dependencies": { - "reflect-metadata": "^0.1.13" - } - }, - "node_modules/table": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", - "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", - "dev": true, - "dependencies": { - "ajv": "^8.0.1", - "lodash.clonedeep": "^4.5.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.6.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", - "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/teeny-request": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.1.3.tgz", - "integrity": "sha512-Ew3aoFzgQEatLA5OBIjdr1DWJUaC1xardG+qbPPo5k/y/3fMwXLxpjh5UB5dVfElktLaQbbMs80chkz53ByvSg==", - "optional": true, - "dependencies": { - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.1", - "stream-events": "^1.0.5", - "uuid": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/teeny-request/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "optional": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" - }, - "node_modules/traverse": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", - "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", - "engines": { - "node": "*" - } - }, - "node_modules/ts-fetch": { - "version": "0.1.0", - "resolved": "git+ssh://git@github.com/panaC/ts_fetch.git#7f585951111aa0e9cb7fe7f99bdd927a9261cd7b", - "integrity": "sha512-2/l4Nka27XgPGCK7PZL8DNFW1BYcf28uPaoYAmF05L94bmvgYx0vkqTAXVRWz2hle7AE5xdBRfk7/06w0nWikg==", - "license": "Apache-2.0", - "dependencies": { - "fetch-cookie": "^1.0.0", - "node-fetch": "^2.6.1", - "tough-cookie": "^4.0.0" - } - }, - "node_modules/ts-fetch/node_modules/tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "optional": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "optional": true, - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/unit-compare": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unit-compare/-/unit-compare-1.0.1.tgz", - "integrity": "sha1-DHRZ8OW/U2N+qHPKPO4Y3i7so4Y=", - "dependencies": { - "moment": "^2.14.1" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/unzipper": { - "version": "0.10.11", - "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz", - "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", - "dependencies": { - "big-integer": "^1.6.17", - "binary": "~0.3.0", - "bluebird": "~3.4.1", - "buffer-indexof-polyfill": "~1.0.0", - "duplexer2": "~0.1.4", - "fstream": "^1.0.12", - "graceful-fs": "^4.2.2", - "listenercount": "~1.0.1", - "readable-stream": "~2.3.6", - "setimmediate": "~1.0.4" - } - }, - "node_modules/unzipper/node_modules/bluebird": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", - "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=" - }, - "node_modules/unzipper/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/unzipper/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/urijs": { - "version": "1.19.7", - "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.7.tgz", - "integrity": "sha512-Id+IKjdU0Hx+7Zx717jwLPsPeUqz7rAtuVBRLLs+qn+J2nf9NGITWVCxcijgYxBqe83C7sqsQPs6H1pyz3x9gA==" - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "optional": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "optional": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/xmldom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz", - "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/xpath": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz", - "integrity": "sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==", - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "optional": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "optional": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "optional": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "node_modules/yazl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", - "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", - "dependencies": { - "buffer-crc32": "~0.2.3" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "optional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, + "lockfileVersion": 1, "dependencies": { "@assistant/conversation": { "version": "3.8.1", @@ -4619,149 +14,37 @@ "@types/node": "12.12.24", "debug": "^3.1.0", "google-auth-library": "^6.1.0" - } - }, - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", - "dev": true - }, - "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "@types/node": { + "version": "12.12.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.24.tgz", + "integrity": "sha512-1Ciqv9pqwVtW6FsIUKSZNB82E5Cu1I2bBTj1xuIHXLe/1zYLl3956Nbhg2MzSYHVfl9/rmanjbQIb7LibfCnug==" }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "requires": { - "ms": "2.1.2" + "ms": "^2.1.1" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "@firebase/app": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.7.1.tgz", - "integrity": "sha512-B4z6E1EPQc0mOjF35IPKdDRCFnT/fNQIHfM+v7F9obB7ItPhGILK3LxaQfuampSQpF6GG6TPFDbrWK6myXAq+g==", - "peer": true, - "requires": { - "@firebase/component": "0.5.7", - "@firebase/logger": "0.3.0", - "@firebase/util": "1.4.0", - "tslib": "^2.1.0" - } - }, - "@firebase/app-compat": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.1.2.tgz", - "integrity": "sha512-kF1maoqA8bZqJ4v/ojVvA7kIyyXEPkJmL48otGrC8LIgdcen7xCx3JFDe0DGeQywg+qujvdkJz/TptFN1cvAgw==", - "peer": true, - "requires": { - "@firebase/app": "0.7.1", - "@firebase/component": "0.5.7", - "@firebase/logger": "0.3.0", - "@firebase/util": "1.4.0", - "tslib": "^2.1.0" + "google-auth-library": { + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.6.tgz", + "integrity": "sha512-Q+ZjUEvLQj/lrVHF/IQwRo6p3s8Nc44Zk/DALsN+ac3T4HY/g/3rrufkgtl+nZ1TW7DNAw5cTChdVp4apUXVgQ==", + "requires": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" + } + } } }, "@firebase/app-types": { @@ -4772,8 +55,7 @@ "@firebase/auth-interop-types": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz", - "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==", - "requires": {} + "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==" }, "@firebase/component": { "version": "0.5.7", @@ -4785,9 +67,9 @@ } }, "@firebase/database": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.12.1.tgz", - "integrity": "sha512-Ethk0hc476qnkSKNBa+8Yc7iM8AO69HYWsaD+QUC983FZtnuMyNLHtEeSUbLQYvyHo7cOjcc52slop14WmfZeQ==", + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.12.2.tgz", + "integrity": "sha512-Y1LZR1LIQM8YKMkeUPpAq3/e53hcfcXO+JEZ6vCzBeD6xRawqmpw6B5/DzePdCNNvjcqheXzSaR7T39eRZo/wA==", "requires": { "@firebase/auth-interop-types": "0.1.6", "@firebase/component": "0.5.7", @@ -4798,12 +80,12 @@ } }, "@firebase/database-compat": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.1.1.tgz", - "integrity": "sha512-K3DFWiw0YkLZtlfA9TOGPw6zVXKu5dQ1XqIGztUufFVRYW8IizReXVxzSSmJNR4Adr2LiU9j66Wenc6e5UfwaQ==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.1.2.tgz", + "integrity": "sha512-sV32QIRSNIBj/6OYtpmPzA/SfQz1/NBZbhxg9dIhGaSt9e5HaMxXRuz2lImudX0Sd/v8DKdExrxa++K6rKrRtA==", "requires": { "@firebase/component": "0.5.7", - "@firebase/database": "0.12.1", + "@firebase/database": "0.12.2", "@firebase/database-types": "0.9.1", "@firebase/logger": "0.3.0", "@firebase/util": "1.4.0", @@ -4853,9 +135,9 @@ } }, "@google-cloud/common": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.7.2.tgz", - "integrity": "sha512-5Q9f74IbZaY6xAwJSNFy5SrGwbm1j7mpv+6A/r+K2dymjsXBH5UauB0tziaMwWoVVaMq1IQnZF9lgtfqqvxcUg==", + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.7.4.tgz", + "integrity": "sha512-JO4a8l/N6fkHZ+vWgNYgcNoZh1/m6kqv8F7+NpBkGqs7NzUtkmE9WdvHaNUwAOm1mIqbuX2wXKNfAZfqZr+vMg==", "optional": true, "requires": { "@google-cloud/projectify": "^2.0.0", @@ -4864,28 +146,9 @@ "duplexify": "^4.1.1", "ent": "^2.2.0", "extend": "^3.0.2", - "google-auth-library": "^7.0.2", + "google-auth-library": "^7.9.2", "retry-request": "^4.2.2", "teeny-request": "^7.0.0" - }, - "dependencies": { - "google-auth-library": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.10.0.tgz", - "integrity": "sha512-ICsqaU+lxMHVlDUzMrfVIEqnARw2AwBiZ/2KnNM6BcTf9Nott+Af87DTIzmlnW865p3REUP2MVL0xkPC3a61aQ==", - "optional": true, - "requires": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - } - } } }, "@google-cloud/firestore": { @@ -4923,12 +186,12 @@ "optional": true }, "@google-cloud/storage": { - "version": "5.14.4", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.14.4.tgz", - "integrity": "sha512-CjpGuk+ZZB7b3yMXPQrPb0TMIhXqbDzrGxngeSl2S2fItFp2pZDnYhvFuB0/8S73cA2T/4x3g1tl6PB1OuuaoQ==", + "version": "5.15.3", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.15.3.tgz", + "integrity": "sha512-a2Y+mvfbzznWorQiv6c+qdPDlBpe47tikV8tpQSnvYXz1Ed/rjin41k2nKUQUcAPGHtYeTzGfKnCNKC+lv8qRg==", "optional": true, "requires": { - "@google-cloud/common": "^3.7.0", + "@google-cloud/common": "^3.7.4", "@google-cloud/paginator": "^3.0.0", "@google-cloud/promisify": "^2.0.0", "arrify": "^2.0.0", @@ -4950,26 +213,19 @@ } }, "@grpc/grpc-js": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.7.tgz", - "integrity": "sha512-CKQVuwuSPh40tgOkR7c0ZisxYRiN05PcKPW72mQL5y++qd7CwBRoaJZvU5xfXnCJDFBmS3qZGQ71Frx6Ofo2XA==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.4.2.tgz", + "integrity": "sha512-aUN6oGk9un8rfYWz73nQgFxPCYJQYd8LpIGguZHBsNduBMyqG6EWANrsVBuTG+nl/l4dKb3x+qi1l9+oxDxqGg==", "optional": true, "requires": { + "@grpc/proto-loader": "^0.6.4", "@types/node": ">=12.12.47" - }, - "dependencies": { - "@types/node": { - "version": "16.10.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.2.tgz", - "integrity": "sha512-zCclL4/rx+W5SQTzFs9wyvvyCwoK9QtBpratqz2IYJ3O8Umrn0m3nsTv0wQBk9sRGpvUe9CwPDrQFB10f1FIjQ==", - "optional": true - } } }, "@grpc/proto-loader": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.5.tgz", - "integrity": "sha512-GZdzyVQI1Bln/kCzIYgTKu+rQJ5dno0gVrfmLe4jqQu7T2e7svSwJzpCBqVU5hhBSJP3peuPjOMWsj5GR61YmQ==", + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.6.tgz", + "integrity": "sha512-cdMaPZ8AiFz6ua6PUbP+LKbhwJbFXnrQ/mlnKGUyzDUZ3wp7vPLksnmLCBX6SHgSmjX7CbNVNLFYD5GmmjO4GQ==", "optional": true, "requires": { "@types/long": "^4.0.1", @@ -4979,40 +235,6 @@ "yargs": "^16.1.1" } }, - "@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", - "dev": true - }, "@panva/asn1.js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", @@ -5159,9 +381,9 @@ } }, "@types/lodash": { - "version": "4.14.175", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.175.tgz", - "integrity": "sha512-XmdEOrKQ8a1Y/yxQFOMbC47G/V2VDO1GvMRnl4O75M4GW/abC5tnfzadQYkqEveqRM1dEJGFFegfPNA2vvx2iw==", + "version": "4.14.176", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.176.tgz", + "integrity": "sha512-xZmuPTa3rlZoIbtDUyJKZQimJV3bxCmzMIO2c9Pz9afyDro6kr7R79GwcB6mRhuoPmV2p1Vb66WOJH7F886WKQ==", "dev": true }, "@types/long": { @@ -5176,9 +398,9 @@ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, "@types/node": { - "version": "12.12.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.24.tgz", - "integrity": "sha512-1Ciqv9pqwVtW6FsIUKSZNB82E5Cu1I2bBTj1xuIHXLe/1zYLl3956Nbhg2MzSYHVfl9/rmanjbQIb7LibfCnug==" + "version": "16.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz", + "integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==" }, "@types/qs": { "version": "6.9.7", @@ -5221,40 +443,12 @@ "negotiator": "0.6.2" } }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "requires": { "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, "ajv": { @@ -5268,36 +462,21 @@ "uri-js": "^4.2.2" } }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "devOptional": true + "optional": true }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "devOptional": true, + "optional": true, "requires": { "color-convert": "^2.0.1" } }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -5321,12 +500,6 @@ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, "async-retry": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", @@ -5370,9 +543,9 @@ } }, "big-integer": { - "version": "1.6.49", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.49.tgz", - "integrity": "sha512-KJ7VhqH+f/BOt9a3yMwJNmcZjG53ijWMTjSAGMveQWyLwqIiwkjNP5PFgDob3Snnx86SjDj6I89fIbv0dkQeNw==" + "version": "1.6.50", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.50.tgz", + "integrity": "sha512-+O2uoQWFRo8ysZNo/rjtri2jIwjr3XfeAgRjAUADRqGG+ZITvyn8J1kvXLTaKVr3hhGXk+f23tKfdzmklVM9vQ==" }, "bignumber.js": { "version": "9.0.1", @@ -5467,12 +640,6 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -5486,16 +653,6 @@ "traverse": ">=0.3.0 <0.4" } }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -5511,7 +668,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "devOptional": true, + "optional": true, "requires": { "color-name": "~1.1.4" } @@ -5520,7 +677,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "devOptional": true + "optional": true }, "combined-stream": { "version": "1.0.8", @@ -5564,6 +721,13 @@ "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", "requires": { "safe-buffer": "5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, "content-type": { @@ -5595,17 +759,6 @@ "vary": "^1" } }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, "crypto-random-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", @@ -5621,25 +774,19 @@ } }, "date-and-time": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-2.0.0.tgz", - "integrity": "sha512-HJSzj25iPm8E01nt+rSmCIlwjsmjvKfUivG/kXBglpymcHF1FolWAqWwTEV4FvN1Lx5UjPf0J1W4H8yQsVBfFg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-2.0.1.tgz", + "integrity": "sha512-O7Xe5dLaqvY/aF/MFWArsAM1J4j7w1CSZlPCX9uHgmb+6SbkPd8Q4YOvfvH/cZGvFlJFfHOZKxQtmMUOoZhc/w==", "optional": true }, "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -5663,15 +810,6 @@ "streamsearch": "0.1.2" } }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, "dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -5703,6 +841,11 @@ "util-deprecate": "~1.0.1" } }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -5751,7 +894,7 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "devOptional": true + "optional": true }, "encodeurl": { "version": "1.0.2", @@ -5767,15 +910,6 @@ "once": "^1.4.0" } }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, "ent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", @@ -5798,188 +932,6 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "eslint-config-google": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", - "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", - "dev": true, - "requires": {} - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -6039,6 +991,11 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" } } }, @@ -6062,12 +1019,6 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, "fast-text-encoding": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", @@ -6097,15 +1048,6 @@ "tough-cookie": "^2.3.3 || ^3.0.1 || ^4.0.0" } }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, "file-js": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/file-js/-/file-js-0.3.0.tgz", @@ -6177,13 +1119,6 @@ "jsonwebtoken": "^8.5.1", "jwks-rsa": "^2.0.2", "node-forge": "^0.10.0" - }, - "dependencies": { - "@types/node": { - "version": "16.10.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.2.tgz", - "integrity": "sha512-zCclL4/rx+W5SQTzFs9wyvvyCwoK9QtBpratqz2IYJ3O8Umrn0m3nsTv0wQBk9sRGpvUe9CwPDrQFB10f1FIjQ==" - } } }, "firebase-functions": { @@ -6220,22 +1155,6 @@ "lodash": "^4.17.5" } }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", - "dev": true - }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -6275,23 +1194,13 @@ "inherits": "~2.0.0", "mkdirp": ">=0.5 0", "rimraf": "2" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - } } }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "devOptional": true + "optional": true }, "gaxios": { "version": "4.3.2", @@ -6327,25 +1236,6 @@ "google-auth-library": "^7.0.0", "pumpify": "^2.0.0", "stream-events": "^1.0.4" - }, - "dependencies": { - "google-auth-library": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.10.0.tgz", - "integrity": "sha512-ICsqaU+lxMHVlDUzMrfVIEqnARw2AwBiZ/2KnNM6BcTf9Nott+Af87DTIzmlnW865p3REUP2MVL0xkPC3a61aQ==", - "optional": true, - "requires": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - } - } } }, "get-caller-file": { @@ -6381,28 +1271,11 @@ "path-is-absolute": "^1.0.0" } }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, "google-auth-library": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.6.tgz", - "integrity": "sha512-Q+ZjUEvLQj/lrVHF/IQwRo6p3s8Nc44Zk/DALsN+ac3T4HY/g/3rrufkgtl+nZ1TW7DNAw5cTChdVp4apUXVgQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.10.1.tgz", + "integrity": "sha512-nQxgM1ZopUMcpMnu95kOSzI+9tJl4YDOZJomSTBGlRLpxfBopdwto7WvzoI87HuN0nQqVETgOsHi/C/po1rppA==", + "optional": true, "requires": { "arrify": "^2.0.0", "base64-js": "^1.3.0", @@ -6416,12 +1289,12 @@ } }, "google-gax": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.26.0.tgz", - "integrity": "sha512-D/8fjTydl9p3ejxuW3ZVHVZqKzz6zYaz5MMEucijsJonJ4RHqWAzHFKZMKSc7yyUiTEBGqG7nU2S8NUPUUYDEA==", + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.28.0.tgz", + "integrity": "sha512-kuqc8a4+CTCMBcF3tlOL7Sa74JWkTzcZxatAQTCVK35WToXkHnJ0qncFOJuegUv3EbV9IQY4j/+NZdFLv+lbTA==", "optional": true, "requires": { - "@grpc/grpc-js": "~1.3.0", + "@grpc/grpc-js": "~1.4.0", "@grpc/proto-loader": "^0.6.1", "@types/long": "^4.0.0", "abort-controller": "^3.0.0", @@ -6434,25 +1307,6 @@ "proto3-json-serializer": "^0.1.1", "protobufjs": "6.11.2", "retry-request": "^4.0.0" - }, - "dependencies": { - "google-auth-library": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.10.0.tgz", - "integrity": "sha512-ICsqaU+lxMHVlDUzMrfVIEqnARw2AwBiZ/2KnNM6BcTf9Nott+Af87DTIzmlnW865p3REUP2MVL0xkPC3a61aQ==", - "optional": true, - "requires": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - } - } } }, "google-p12-pem": { @@ -6492,12 +1346,6 @@ "har-schema": "^2.0.0" } }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, "hash-stream-validation": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.4.tgz", @@ -6535,25 +1383,8 @@ "optional": true, "requires": { "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "optional": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "optional": true - } + "agent-base": "6", + "debug": "4" } }, "http-signature": { @@ -6573,21 +1404,6 @@ "requires": { "agent-base": "6", "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, "iconv-lite": { @@ -6598,12 +1414,6 @@ "safer-buffer": ">= 2.1.2 < 3" } }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, "image-size": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.0.tgz", @@ -6612,21 +1422,11 @@ "queue": "6.0.2" } }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "devOptional": true + "optional": true }, "inflight": { "version": "1.0.6", @@ -6647,26 +1447,11 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "devOptional": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } + "optional": true }, "is-obj": { "version": "2.0.0", @@ -6695,12 +1480,6 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -6714,22 +1493,6 @@ "@panva/asn1.js": "^1.0.0" } }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", @@ -6753,12 +1516,6 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -6829,30 +1586,15 @@ } }, "jwks-rsa": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.0.4.tgz", - "integrity": "sha512-iJqVCECYZZ+3oPmY1qXv3Fq+3ywDtuNEVBvG41pPlaR0zyGxa12nC0beAOBBUhETJmc05puS50mRQN4NkCGhmg==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.0.5.tgz", + "integrity": "sha512-fliHfsiBRzEU0nXzSvwnh0hynzGB0WihF+CinKbSRlaqRxbqqKf2xbBPgwc8mzf18/WgwlG8e5eTpfSTBcU4DQ==", "requires": { "@types/express-jwt": "0.0.42", "debug": "^4.3.2", "jose": "^2.0.5", "limiter": "^1.1.5", "lru-memoizer": "^2.1.4" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, "jws": { @@ -6864,16 +1606,6 @@ "safe-buffer": "^5.0.1" } }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, "limiter": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", @@ -6930,23 +1662,11 @@ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, "lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true - }, "long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", @@ -6993,14 +1713,6 @@ "optional": true, "requires": { "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "optional": true - } } }, "media-typer": { @@ -7027,22 +1739,14 @@ "mime-db": { "version": "1.50.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", - "optional": true + "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==" }, "mime-types": { - "version": "2.1.32", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", - "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "version": "2.1.33", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", + "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", "requires": { - "mime-db": "1.49.0" - }, - "dependencies": { - "mime-db": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", - "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==" - } + "mime-db": "1.50.0" } }, "minimatch": { @@ -7072,20 +1776,14 @@ "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" }, "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "nanoid": { - "version": "3.1.28", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.28.tgz", - "integrity": "sha512-gSu9VZ2HtmoKYe/lmyPFES5nknFrHa+/DT9muUFWFMi6Jh9E1I7bkvlQ8xxf1Kos9pi9o8lBnIOkatMhKX/YUw==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true + "version": "3.1.30", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz", + "integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==" }, "negotiator": { "version": "0.6.2", @@ -7143,9 +1841,8 @@ } }, "opds-fetcher-parser": { - "version": "git+ssh://git@github.com/panaC/opds_fetcher_parser.git#efec695f50b386071ccf935396f0a8ea4750c9ae", - "integrity": "sha512-vhOHEBu7Bs9y0XHgGo8u6ntgrjAtclGZE61cP11F1HBwBnF8s7w+Vlagc7MJq2xMy0RuMN45lzVoco8Rl9petQ==", - "from": "opds-fetcher-parser@github:panaC/opds_fetcher_parser#efec695f50b386071ccf935396f0a8ea4750c9ae", + "version": "github:panaC/opds_fetcher_parser#efec695f50b386071ccf935396f0a8ea4750c9ae", + "from": "github:panaC/opds_fetcher_parser#efec695f50b386071ccf935396f0a8ea4750c9ae", "requires": { "moment": "^2.29.1", "nanoid": "^3.1.23", @@ -7155,20 +1852,6 @@ "ts-fetch": "github:panaC/ts_fetch#7f585951111aa0e9cb7fe7f99bdd927a9261cd7b" } }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -7178,15 +1861,6 @@ "yocto-queue": "^0.1.0" } }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -7197,12 +1871,6 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -7218,23 +1886,11 @@ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, "proper-lockfile": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-1.2.0.tgz", @@ -7254,9 +1910,9 @@ } }, "proto3-json-serializer": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-0.1.4.tgz", - "integrity": "sha512-bFzdsKU/zaTobWrRxRniMZIzzcgKYlmBWL1gAcTXZ2M7TQTGPI0JoYYs6bN7tpWj59ZCfwg7Ii/A2e8BbQGYnQ==", + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-0.1.5.tgz", + "integrity": "sha512-G395jcZkgNXNeS+6FGqd09TsXeoCs9wmBWByDiwFy7Yd7HD8pyfyvf6q+rGh7PhT4AshRpG4NowzoKYUtkNjKg==", "optional": true }, "protobufjs": { @@ -7278,14 +1934,6 @@ "@types/long": "^4.0.1", "@types/node": ">=13.7.0", "long": "^4.0.0" - }, - "dependencies": { - "@types/node": { - "version": "16.10.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.2.tgz", - "integrity": "sha512-zCclL4/rx+W5SQTzFs9wyvvyCwoK9QtBpratqz2IYJ3O8Umrn0m3nsTv0wQBk9sRGpvUe9CwPDrQFB10f1FIjQ==", - "optional": true - } } }, "proxy-addr": { @@ -7347,109 +1995,64 @@ } }, "r2-lcp-js": { - "version": "1.0.32", - "resolved": "https://registry.npmjs.org/r2-lcp-js/-/r2-lcp-js-1.0.32.tgz", - "integrity": "sha512-cNpOc9ZWatCe7WPMQxVfA7p1xtynrU7eWZ/Cw41+zkKRUsOU4b+CTtwq1APMut+dMhnEHNIjDVUqxGBnFUa7dw==", + "version": "1.0.33", + "resolved": "https://registry.npmjs.org/r2-lcp-js/-/r2-lcp-js-1.0.33.tgz", + "integrity": "sha512-WNPVjHd1v8appnAqGZ/B8DlRm4k0JdixOc1TSwF+FSrjcBidG+CWijozFEBdPF+DT6FQAZcBc91B+Oc4qw3OJg==", "requires": { "bindings": "^1.5.0", "debug": "^4.3.2", "moment": "^2.29.1", - "r2-utils-js": "^1.0.26", + "r2-utils-js": "^1.0.27", "request": "^2.88.2", "request-promise-native": "^1.0.9", "ta-json-x": "^2.5.3", "tslib": "^2.3.1", "urijs": "^1.19.7" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, "r2-opds-js": { - "version": "1.0.36", - "resolved": "https://registry.npmjs.org/r2-opds-js/-/r2-opds-js-1.0.36.tgz", - "integrity": "sha512-JQB92qGzJWTO1l8NkZ3AhsQXm197Ny2pnU2NtakjWPnASnw60DJxs14yxXHKjTDZZzLI+XzsWYJJ6BKitIN55w==", + "version": "1.0.37", + "resolved": "https://registry.npmjs.org/r2-opds-js/-/r2-opds-js-1.0.37.tgz", + "integrity": "sha512-7LEG7S9RBJ94MfYTy5+sCDnbA5qf4a3qSoxTYWorSac7MRyjkZdRusWkUl7LW438t78wnPCx3TDeYowXVVDOrw==", "requires": { "debug": "^4.3.2", - "r2-lcp-js": "^1.0.31", - "r2-shared-js": "^1.0.52", - "r2-utils-js": "^1.0.26", + "r2-lcp-js": "^1.0.33", + "r2-shared-js": "^1.0.53", + "r2-utils-js": "^1.0.27", "ta-json-x": "^2.5.3", "tslib": "^2.3.1", "xmldom": "^0.6.0" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, "r2-shared-js": { - "version": "1.0.52", - "resolved": "https://registry.npmjs.org/r2-shared-js/-/r2-shared-js-1.0.52.tgz", - "integrity": "sha512-GYPdqK7FPUSczC68ZHqz3gFL98VZU/UCQtlgknxvJdDrM7+2Pz805X6iMUMzr1mkL203/Wl8mm+O5BsjQnc8tw==", + "version": "1.0.53", + "resolved": "https://registry.npmjs.org/r2-shared-js/-/r2-shared-js-1.0.53.tgz", + "integrity": "sha512-1LyAd5Ebhyfe2gRFg8wE0wS9yK+bYDBfRZLpCxCX5O3JNdSwuVwLAff6qLhk7ExagifFRB4ZUNMpW1n3zEUi+Q==", "requires": { "debug": "^4.3.2", "fast-deep-equal": "^3.1.3", "image-size": "^1.0.0", - "mime-types": "^2.1.32", + "mime-types": "^2.1.33", "moment": "^2.29.1", - "r2-lcp-js": "^1.0.31", - "r2-utils-js": "^1.0.26", - "slugify": "^1.6.0", + "r2-lcp-js": "^1.0.33", + "r2-utils-js": "^1.0.27", + "slugify": "^1.6.1", "ta-json-x": "^2.5.3", "tslib": "^2.3.1", "xmldom": "^0.6.0", "xpath": "^0.0.32", "yazl": "^2.5.1" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, "r2-utils-js": { - "version": "1.0.26", - "resolved": "https://registry.npmjs.org/r2-utils-js/-/r2-utils-js-1.0.26.tgz", - "integrity": "sha512-8t9JIafLP1IXtpCcEqRxSlLtHrGPai3qidAq3Xe3sQTCNv29WZtHPglGSZX95BPPFDhIQfM9CiVvkbgReFFZ4Q==", + "version": "1.0.27", + "resolved": "https://registry.npmjs.org/r2-utils-js/-/r2-utils-js-1.0.27.tgz", + "integrity": "sha512-uZ0P/JBKY16JAsL5FwH/r2k+9Jq30i7IdWxsa26mki/2DHALE4lv+Qs80kU68pHWKXS+eeriyCkCTCmI32TJTw==", "requires": { "@types/xmldom": "^0.1.31", "debug": "^4.3.2", - "filehound": "^1.17.4", - "node-stream-zip": "^1.14.0", + "filehound": "^1.17.5", + "node-stream-zip": "^1.15.0", "reflect-metadata": "^0.1.13", "request": "^2.88.2", "request-promise-native": "^1.0.9", @@ -7459,21 +2062,6 @@ "xpath": "^0.0.32", "yauzl": "^2.10.0", "yazl": "^2.5.1" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, "range-parser": { @@ -7508,12 +2096,6 @@ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -7545,6 +2127,11 @@ "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" } } }, @@ -7572,18 +2159,6 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "optional": true }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, "retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -7598,38 +2173,20 @@ "requires": { "debug": "^4.1.1", "extend": "^3.0.2" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "optional": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "optional": true - } } }, "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "requires": { "glob": "^7.1.3" } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "safer-buffer": { "version": "2.1.2", @@ -7637,13 +2194,10 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "optional": true }, "send": { "version": "0.17.1", @@ -7713,42 +2267,16 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, "signal-exit": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", "optional": true }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, "slugify": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.0.tgz", - "integrity": "sha512-FkMq+MQc5hzYgM86nLuHI98Acwi3p4wX+a5BO9Hhw4JdK4L7WueIiZ4tXEobImPqBz2sVcV0+Mu3GRB30IGang==" + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.1.tgz", + "integrity": "sha512-5ofqMTbetNhxlzjYYLBaZFQd6oiTuSkQlyfPEFIMwgUABlZQ0hbk5xIV9Ydd5jghWeRoO7GkiJliUvTpLOjNRA==" }, "snakeize": { "version": "0.1.0", @@ -7756,12 +2284,6 @@ "integrity": "sha1-EMCI2LWOsHazIpu1oE4jLOEmQi0=", "optional": true }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", @@ -7808,64 +2330,41 @@ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "optional": true, - "requires": { - "safe-buffer": "~5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "optional": true - } - } - }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "devOptional": true, + "optional": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "optional": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "devOptional": true, + "optional": true, "requires": { "ansi-regex": "^5.0.1" } }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, "stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=", "optional": true }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, "ta-json-x": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/ta-json-x/-/ta-json-x-2.5.3.tgz", @@ -7874,40 +2373,6 @@ "reflect-metadata": "^0.1.13" } }, - "table": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", - "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", - "dev": true, - "requires": { - "ajv": "^8.0.1", - "lodash.clonedeep": "^4.5.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.6.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", - "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } - } - }, "teeny-request": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.1.3.tgz", @@ -7919,22 +2384,8 @@ "node-fetch": "^2.6.1", "stream-events": "^1.0.5", "uuid": "^8.0.0" - }, - "dependencies": { - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "optional": true - } } }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", @@ -7960,9 +2411,8 @@ "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=" }, "ts-fetch": { - "version": "git+ssh://git@github.com/panaC/ts_fetch.git#7f585951111aa0e9cb7fe7f99bdd927a9261cd7b", - "integrity": "sha512-2/l4Nka27XgPGCK7PZL8DNFW1BYcf28uPaoYAmF05L94bmvgYx0vkqTAXVRWz2hle7AE5xdBRfk7/06w0nWikg==", - "from": "ts-fetch@github:panaC/ts_fetch#7f585951111aa0e9cb7fe7f99bdd927a9261cd7b", + "version": "github:panaC/ts_fetch#7f585951111aa0e9cb7fe7f99bdd927a9261cd7b", + "from": "github:panaC/ts_fetch#7f585951111aa0e9cb7fe7f99bdd927a9261cd7b", "requires": { "fetch-cookie": "^1.0.0", "node-fetch": "^2.6.1", @@ -7999,21 +2449,6 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -8095,6 +2530,11 @@ "util-deprecate": "~1.0.1" } }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -8129,15 +2569,10 @@ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "optional": true }, "vary": { "version": "1.1.2", @@ -8183,21 +2618,6 @@ "webidl-conversions": "^3.0.0" } }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index 358c68f6..2c2886ef 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -1,9 +1,7 @@ { "name": "functions", - "version": "0.1.0", "description": "Cloud Functions for Firebase", "scripts": { - "lint": "eslint .", "serve": "firebase emulators:start --only functions", "shell": "firebase functions:shell", "start": "npm run shell", @@ -11,18 +9,16 @@ "logs": "firebase functions:log" }, "engines": { - "node": "16" + "node": "14" }, "main": "index.js", "dependencies": { "@assistant/conversation": "^3.0.0", - "firebase-admin": "^9.11.1", + "firebase-admin": "^9.8.0", "firebase-functions": "^3.14.1", "opds-fetcher-parser": "github:panaC/opds_fetcher_parser#efec695f50b386071ccf935396f0a8ea4750c9ae" }, "devDependencies": { - "eslint": "^7.6.0", - "eslint-config-google": "^0.14.0", "firebase-functions-test": "^0.2.0" }, "private": true From cd46936e75f96c5ddf4784d2b93892b8c0c5fba9 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 28 Oct 2021 15:54:40 +0200 Subject: [PATCH 002/180] fix project-id in actions --- .github/workflows/functions-dev.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/functions-dev.yml b/.github/workflows/functions-dev.yml index 2570e8fa..7a03ee79 100644 --- a/.github/workflows/functions-dev.yml +++ b/.github/workflows/functions-dev.yml @@ -19,6 +19,7 @@ jobs: env: working-directory: './webhooks/functions' + project-id: 'valentin-5' defaults: run: working-directory: './webhooks/functions' @@ -44,7 +45,7 @@ jobs: - name: set commit name to function config uses: w9jds/firebase-action@master with: - args: functions:config:set debug.message=\"${{ github.event.head_commit.message }}\" + args: functions:config:set debug.message=\"${{ github.event.head_commit.message }}\" --project ${{ env.project-id }} env: FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} PROJECT_PATH: './webhooks' @@ -52,7 +53,7 @@ jobs: - name: Deploy to Firebase uses: w9jds/firebase-action@master with: - args: deploy --only \"functions:ActionsOnGoogleFulfillment\" --project valentin-5 --message \"${{ github.event.head_commit.message }}\" + args: deploy --only \"functions:ActionsOnGoogleFulfillment\" --project ${{ env.project-id }} --message \"${{ github.event.head_commit.message }}\" env: FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} PROJECT_PATH: './webhooks' From 3dc8d18618403c92d0f8ec31c9d37c940fc893e2 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Fri, 29 Oct 2021 16:59:42 +0200 Subject: [PATCH 003/180] push github actions test sdk DEV --- .github/workflows/sdk-test-dev.yml | 33 ++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .github/workflows/sdk-test-dev.yml diff --git a/.github/workflows/sdk-test-dev.yml b/.github/workflows/sdk-test-dev.yml new file mode 100644 index 00000000..4a35d82a --- /dev/null +++ b/.github/workflows/sdk-test-dev.yml @@ -0,0 +1,33 @@ + +name: sdk test dev + +on: + push: + branches: [ develop ] + # paths: + +jobs: + sdk-test-prod: + name: "Test sdk DEV" + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [14.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + defaults: + run: + working-directory: './test/dev' + + steps: + + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node }} + + - name: save service_account + run: echo $SECRET >> service_account.json + env: + SECRET : ${{ secrets.SERVICE_ACCOUNT_VALENTIN5 }} + - run: npm install + - run: npm test From 9d79e55ce560881363ca87aedc26fd5f3d3c9e33 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Fri, 29 Oct 2021 17:01:42 +0200 Subject: [PATCH 004/180] github action test sdk dev on PR too --- .github/workflows/sdk-test-dev.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/sdk-test-dev.yml b/.github/workflows/sdk-test-dev.yml index 4a35d82a..76e61227 100644 --- a/.github/workflows/sdk-test-dev.yml +++ b/.github/workflows/sdk-test-dev.yml @@ -5,6 +5,8 @@ on: push: branches: [ develop ] # paths: + pull_request: + branches: [ develop ] jobs: sdk-test-prod: From ad565ba788cab53a14620b4858afcc8911a1f17b Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 2 Nov 2021 11:53:37 +0100 Subject: [PATCH 005/180] webhooks: setup_test_sdk --- webhooks/functions/index.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/webhooks/functions/index.js b/webhooks/functions/index.js index 4fd9cb0a..64a7042e 100644 --- a/webhooks/functions/index.js +++ b/webhooks/functions/index.js @@ -74,6 +74,18 @@ async function getPubsFromFeed(url) { return list; } +app.handle("setup_test_sdk", (conv) => { + + const nb = conv.intent.params.number.resolved; + + conv.user.params = { + bearerToken: `test-${nb}`; + } + + conv.add(`setup test ${nb}`); + +}); + // ---------------- // // CONVERSATION START From 891def4ebcb54fbc729680bc389afa60e32ba190 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 2 Nov 2021 12:06:12 +0100 Subject: [PATCH 006/180] fix webhooks setup test sdk --- webhooks/functions/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webhooks/functions/index.js b/webhooks/functions/index.js index 64a7042e..f1955613 100644 --- a/webhooks/functions/index.js +++ b/webhooks/functions/index.js @@ -79,7 +79,7 @@ app.handle("setup_test_sdk", (conv) => { const nb = conv.intent.params.number.resolved; conv.user.params = { - bearerToken: `test-${nb}`; + bearerToken: `test-${nb}`, } conv.add(`setup test ${nb}`); From 38de12450f416bb389f02dd2971ac2e0ae8a088f Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 2 Nov 2021 15:51:50 +0100 Subject: [PATCH 007/180] test/dev: test-1 home+setup --- test/dev/test/constant.ts | 18 ++++++++++++++++++ test/dev/test/test1.ts | 39 ++++++++++----------------------------- 2 files changed, 28 insertions(+), 29 deletions(-) create mode 100644 test/dev/test/constant.ts diff --git a/test/dev/test/constant.ts b/test/dev/test/constant.ts new file mode 100644 index 00000000..d2e9e76d --- /dev/null +++ b/test/dev/test/constant.ts @@ -0,0 +1,18 @@ + +import {env} from 'process'; +import {ok} from 'assert'; + +export const DEFAULT_LOCALE = 'fr-FR'; +export const DEFAULT_SURFACE = 'PHONE'; +export const HOME_PROMPT = "Bienvenue dans l'application d'écoute de livre audio valentin hauy"; +export const MEMBER_PROMPT = "Bienvenue dans l'espace membres. Les commandes possibles sont, sélection, lecture, recherche. Que voulez-vous faire ?"; + +export const PROJECT_ID = env['PROJECT_ID'] || ''; +export const TRIGGER_PHRASE = 'Parler avec valentin audio dev'; + + +console.log(`PROJECT_ID=${PROJECT_ID}`); + +ok(PROJECT_ID, 'no PROJECT_ID'); + + diff --git a/test/dev/test/test1.ts b/test/dev/test/test1.ts index 18307e6c..9f9beb27 100644 --- a/test/dev/test/test1.ts +++ b/test/dev/test/test1.ts @@ -1,22 +1,11 @@ import 'mocha'; -import {env} from 'process'; import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok, rejects} from 'assert'; +import {ok} from 'assert'; import { inspect } from 'util'; +import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -const DEFAULT_LOCALE = 'fr-FR'; -const DEFAULT_SURFACE = 'PHONE'; -const CONTINUE_CONVO_PROMPT = "Bienvenue dans l'application d'écoute de livre audio valentin hauy Que voulez-vous faire ? Vous pouvez dire informations ou espace membres"; - -const PROJECT_ID = env['PROJECT_ID'] || ''; -const TRIGGER_PHRASE = 'Parler avec valentin audio'; - -console.log(`PROJECT_ID=${PROJECT_ID}`); - -ok(PROJECT_ID, 'no PROJECT_ID'); - -// tslint:disable:only-arrow-functions +const TEST_NUM = 1; describe('My Action Test Suite', function () { // Set the timeout for each test run to 60s. @@ -25,25 +14,17 @@ describe('My Action Test Suite', function () { async function startConversation() { await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(CONTINUE_CONVO_PROMPT); - test.assertText(CONTINUE_CONVO_PROMPT); + test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_lvl1'); - - let se = await test.sendQuery("espace membres"); - console.log(se); - - // test.assertSpeech("Bienvenue dans l'espace membres. Les commandes possibles sont, sélection, lecture, recherche. Que voulez-vous faire ?"); - let resp = test.getLatestResponse(); - console.log(inspect(resp, {showHidden: false, depth: null, colors: true})); + test.assertScene('home_members_lvl2'); - test.assertText("Pour continuer d'utiliser valentin audio, je dois associer votre compte valentin audio à Google. Êtes-vous d'accord ?"); + await test.sendQuery(`setup test ${TEST_NUM}`); - se = await test.sendQuery("oui"); - console.log(se); + test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - resp = test.getLatestResponse(); - console.dir(resp); + // + // resp = test.getLatestResponse(); } before('before all', async () => { From 2f2b83804dcc8bf3ac89ad579055591ec6a85246 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 3 Nov 2021 13:33:57 +0100 Subject: [PATCH 008/180] webhooks fix test player --- webhooks/functions/index.js | 47 +++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/webhooks/functions/index.js b/webhooks/functions/index.js index f1955613..47560372 100644 --- a/webhooks/functions/index.js +++ b/webhooks/functions/index.js @@ -74,6 +74,49 @@ async function getPubsFromFeed(url) { return list; } +////////// +// TEST // +////////// + +app.handle("test_player_sdk", (conv) => { + + const nb = conv.intent.params.number.resolved; + + switch (nb) { + + case 123: + + conv.user.params = { + ...conv.user.params, + p_i: 2, + p_n: "therese_raquin_emile_zola.json", + p_t: 123, + player: { + ...conv.user.params.player || {}, + ["therese_raquin_emile_zola.json"]: { + p_i: 2, + p_n: "therese_raquin_emile_zola.json", + p_t: 123, + }, + }, + }; + + break; + + case 456: + + break; + case 789: + + break; + } + + console.log("test_PLAYER"); + console.log(conv.user.params); + + conv.add(`test player ${nb}`); +}); + app.handle("setup_test_sdk", (conv) => { const nb = conv.intent.params.number.resolved; @@ -86,6 +129,10 @@ app.handle("setup_test_sdk", (conv) => { }); +////////// +// TEST // +////////// + // ---------------- // // CONVERSATION START From 45826e63f8f6bf95bb134cde55bd5a2abc89274e Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 3 Nov 2021 13:46:45 +0100 Subject: [PATCH 009/180] fix reprendre la lecture sentence --- webhooks/functions/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webhooks/functions/index.js b/webhooks/functions/index.js index 47560372..193ebbc6 100644 --- a/webhooks/functions/index.js +++ b/webhooks/functions/index.js @@ -408,7 +408,7 @@ app.handle("ask_to_resume_listening_at_last_offset", async (conv) => { const date = history.d; // TODO: use the date info - conv.add("Voulez-vous reprendre la lecture là où c'était arrêtée ?"); + conv.add("Voulez-vous reprendre la lecture là où elle s'était arrêtée ?"); } else { console.log("no need to ask to resume"); conv.scene.next.name = "player"; From 456564b8f5d713184a8e145fcc69b358f26b3d4a Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 3 Nov 2021 14:47:36 +0100 Subject: [PATCH 010/180] some first search and player test on develop --- test/dev/package.json | 3 +- test/dev/test/test2.ts | 57 ++++++ test/dev/test/test3.ts | 63 ++++++ test/dev/test/test4.ts | 258 ++++++++++++++++++++++++ test/dev/test/test5.ts | 215 ++++++++++++++++++++ test/dev/test/test6.ts | 244 +++++++++++++++++++++++ test/dev/test/test7.ts | 254 ++++++++++++++++++++++++ test/dev/test/test8.ts | 432 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 1525 insertions(+), 1 deletion(-) create mode 100644 test/dev/test/test2.ts create mode 100644 test/dev/test/test3.ts create mode 100644 test/dev/test/test4.ts create mode 100644 test/dev/test/test5.ts create mode 100644 test/dev/test/test6.ts create mode 100644 test/dev/test/test7.ts create mode 100644 test/dev/test/test8.ts diff --git a/test/dev/package.json b/test/dev/package.json index b06c8543..62eccfc8 100644 --- a/test/dev/package.json +++ b/test/dev/package.json @@ -6,7 +6,8 @@ "scripts": { "lint": "eslint \"test/*.ts\"", "enable-activity-controls": "env GOOGLE_APPLICATION_CREDENTIALS=$PWD/service_account.json web-and-app-activity-controls", - "test": "npm run lint && env GOOGLE_APPLICATION_CREDENTIALS=$PWD/service_account.json PROJECT_ID=$(cat $PWD/service_account.json| jq -r '.project_id') mocha --recursive --require ts-node/register test/*.ts" + "test": "npm run lint && env GOOGLE_APPLICATION_CREDENTIALS=$PWD/service_account.json PROJECT_ID=$(cat $PWD/service_account.json| jq -r '.project_id') mocha --recursive --require ts-node/register test/*.ts", + "test:file": "npm run lint && env GOOGLE_APPLICATION_CREDENTIALS=$PWD/service_account.json PROJECT_ID=$(cat $PWD/service_account.json| jq -r '.project_id') mocha --recursive --require ts-node/register" }, "author": "", "license": "ISC", diff --git a/test/dev/test/test2.ts b/test/dev/test/test2.ts new file mode 100644 index 00000000..d21e91e0 --- /dev/null +++ b/test/dev/test/test2.ts @@ -0,0 +1,57 @@ +import 'mocha'; + +import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; +import {ok} from 'assert'; +import { inspect } from 'util'; +import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; + +const TEST_NUM = 2; + +describe('My Action Test Suite', function () { + // Set the timeout for each test run to 60s. + this.timeout(60000); + let test: ActionsOnGoogleTestManager; + + async function startConversation() { + await test.sendQuery(TRIGGER_PHRASE); + test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertIntent('actions.intent.MAIN'); + test.assertScene('home_members_lvl2'); + + await test.sendQuery(`setup test ${TEST_NUM}`); + + test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); + + // RECHERCHE + + await test.sendQuery('recherche'); + + test.assertSpeech(`Que voulez-vous écouter ?`); + + await test.sendQuery('test avec aucune publication renvoyés'); + + await test.assertSpeech(`aucun résultat trouvé Que voulez-vous écouter ? Par exemple Zola`); + + // + // resp = test.getLatestResponse(); + } + + before('before all', async () => { + // Load project settings to read project ID and trigger phrase. + test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); + await test.writePreviewFromDraft(); + test.setSuiteLocale(DEFAULT_LOCALE); + test.setSuiteSurface(DEFAULT_SURFACE); + }); + + afterEach('post test cleans', async () => { + test.cleanUpAfterTest(); + }); + + it('search with bad query', async () => { + await startConversation(); + await test.sendQuery("quitter"); + // test.assertConversationEnded(); + }); +}); diff --git a/test/dev/test/test3.ts b/test/dev/test/test3.ts new file mode 100644 index 00000000..8881eda1 --- /dev/null +++ b/test/dev/test/test3.ts @@ -0,0 +1,63 @@ +import 'mocha'; + +import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; +import {ok} from 'assert'; +import { inspect } from 'util'; +import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; + +const TEST_NUM = 3; + +describe('My Action Test Suite', function () { + // Set the timeout for each test run to 60s. + this.timeout(60000); + let test: ActionsOnGoogleTestManager; + + async function startConversation() { + await test.sendQuery(TRIGGER_PHRASE); + test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertIntent('actions.intent.MAIN'); + test.assertScene('home_members_lvl2'); + + await test.sendQuery(`setup test ${TEST_NUM}`); + + test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); + + // RECHERCHE + + await test.sendQuery('recherche'); + + test.assertSpeech(`Que voulez-vous écouter ?`); + + await test.sendQuery('zola'); + + await test.assertSpeech(`Il y a 2 publications :\n Pour choisir une publication dite son numéronumero 1 : Thérèse Raquin de Emile Zola\nnumero 2 : L'assommoir de Emile Zola\n`); + + await test.sendQuery('0'); + + await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. Pour choisir une publication dite son numéro`); + + test.assertScene('select_pub_after_search'); + + // + // resp = test.getLatestResponse(); + } + + before('before all', async () => { + // Load project settings to read project ID and trigger phrase. + test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); + await test.writePreviewFromDraft(); + test.setSuiteLocale(DEFAULT_LOCALE); + test.setSuiteSurface(DEFAULT_SURFACE); + }); + + afterEach('post test cleans', async () => { + test.cleanUpAfterTest(); + }); + + it('search with bad query', async () => { + await startConversation(); + await test.sendQuery("quitter"); + // test.assertConversationEnded(); + }); +}); diff --git a/test/dev/test/test4.ts b/test/dev/test/test4.ts new file mode 100644 index 00000000..dd7ef58f --- /dev/null +++ b/test/dev/test/test4.ts @@ -0,0 +1,258 @@ +import 'mocha'; + +import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; +import {ok} from 'assert'; +import { inspect } from 'util'; +import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; +import * as fs from 'fs'; +import * as chai from 'chai'; + +const TEST_NUM = 4; + +describe('My Action Test Suite', function () { + // Set the timeout for each test run to 60s. + this.timeout(60000); + let test: ActionsOnGoogleTestManager; + + async function startConversation() { + await test.sendQuery(TRIGGER_PHRASE); + test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertIntent('actions.intent.MAIN'); + test.assertScene('home_members_lvl2'); + + await test.sendQuery(`setup test ${TEST_NUM}`); + + test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); + + // RECHERCHE + + await test.sendQuery('recherche'); + + test.assertSpeech(`Que voulez-vous écouter ?`); + + await test.sendQuery('zola'); + + await test.assertSpeech(`Il y a 2 publications :\n Pour choisir une publication dite son numéronumero 1 : Thérèse Raquin de Emile Zola\nnumero 2 : L'assommoir de Emile Zola\n`); + + await test.sendQuery('0'); + + await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. Pour choisir une publication dite son numéro`); + + test.assertScene('select_pub_after_search'); + + await test.sendQuery('1'); + + const resp: any = test.getLatestResponse(); + + // console.log(resp); + // console.log(inspect(resp, {showHidden: false, depth: null, colors: true})); + // + + chai.expect(JSON.stringify(resp.output.actionsBuilderPrompt.content)).to.equal(JSON.stringify({ + "media": { + "optionalMediaControls": [ + "PAUSED", + "STOPPED" + ], + "mediaObjects": [ + { + "name": "Thérèse Raquin - 1", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap01-03.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 2", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap04-06.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 3", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap07-09.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 4", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap10-12.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 5", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap13-16.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 6", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap17-18.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 7", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap19-20.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 8", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap21-22.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 9", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap23-25.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 10", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap26-27.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 11", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap28-29.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 12", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap30-32.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + } + ], + "startOffset": { + "seconds": "0", + "nanos": 0 + }, + "mediaType": "AUDIO" + }, + "content": "media" + })); + + test.assertScene('player'); + + } + + before('before all', async () => { + // Load project settings to read project ID and trigger phrase. + test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); + await test.writePreviewFromDraft(); + test.setSuiteLocale(DEFAULT_LOCALE); + test.setSuiteSurface(DEFAULT_SURFACE); + }); + + afterEach('post test cleans', async () => { + test.cleanUpAfterTest(); + }); + + it('search with bad query', async () => { + await startConversation(); + await test.sendQuery("quitter"); + // test.assertConversationEnded(); + }); +}); diff --git a/test/dev/test/test5.ts b/test/dev/test/test5.ts new file mode 100644 index 00000000..a1b41361 --- /dev/null +++ b/test/dev/test/test5.ts @@ -0,0 +1,215 @@ +import 'mocha'; + +import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; +import {ok} from 'assert'; +import { inspect } from 'util'; +import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; +import * as chai from 'chai'; + +const TEST_NUM = 5; +import * as fs from 'fs'; + +describe('My Action Test Suite', function () { + // Set the timeout for each test run to 60s. + this.timeout(60000); + let test: ActionsOnGoogleTestManager; + + async function startConversation() { + await test.sendQuery(TRIGGER_PHRASE); + test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertIntent('actions.intent.MAIN'); + test.assertScene('home_members_lvl2'); + + await test.sendQuery(`setup test ${TEST_NUM}`); + test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); + + // 123 : player therese_raquin_emile_zola.json + await test.sendQuery(`test player 123`); + test.assertSpeech(`test player 123 ${MEMBER_PROMPT}`); + + // RECHERCHE + + await test.sendQuery('lecture'); + test.assertSpeech(`Voulez-vous reprendre la lecture là où elle s'était arrêtée ?`); + + await test.sendQuery('oui'); + const media = test.getMedia(); + chai.expect(media).to.deep.equal({ + "optionalMediaControls": [ + "PAUSED", + "STOPPED" + ], + "mediaObjects": [ + { + "name": "Thérèse Raquin - 3", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap07-09.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 4", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap10-12.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 5", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap13-16.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 6", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap17-18.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 7", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap19-20.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 8", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap21-22.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 9", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap23-25.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 10", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap26-27.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 11", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap28-29.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 12", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap30-32.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + } + ], + "startOffset": { + "seconds": "123", + "nanos": 0 + }, + "mediaType": "AUDIO" + }); + + + + // + // resp = test.getLatestResponse(); + } + + before('before all', async () => { + // Load project settings to read project ID and trigger phrase. + test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); + await test.writePreviewFromDraft(); + test.setSuiteLocale(DEFAULT_LOCALE); + test.setSuiteSurface(DEFAULT_SURFACE); + }); + + afterEach('post test cleans', async () => { + test.cleanUpAfterTest(); + }); + + it('search with bad query', async () => { + await startConversation(); + await test.sendQuery("quitter"); + // test.assertConversationEnded(); + }); +}); diff --git a/test/dev/test/test6.ts b/test/dev/test/test6.ts new file mode 100644 index 00000000..3cded290 --- /dev/null +++ b/test/dev/test/test6.ts @@ -0,0 +1,244 @@ +import 'mocha'; + +import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; +import {ok} from 'assert'; +import { inspect } from 'util'; +import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; +import * as chai from 'chai'; + +const TEST_NUM = 6; +import * as fs from 'fs'; + +describe('My Action Test Suite', function () { + // Set the timeout for each test run to 60s. + this.timeout(60000); + let test: ActionsOnGoogleTestManager; + + async function startConversation() { + await test.sendQuery(TRIGGER_PHRASE); + test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertIntent('actions.intent.MAIN'); + test.assertScene('home_members_lvl2'); + + await test.sendQuery(`setup test ${TEST_NUM}`); + test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); + + // 123 : player therese_raquin_emile_zola.json + await test.sendQuery(`test player 123`); + test.assertSpeech(`test player 123 ${MEMBER_PROMPT}`); + + // RECHERCHE + + await test.sendQuery('lecture'); + test.assertSpeech(`Voulez-vous reprendre la lecture là où elle s'était arrêtée ?`); + + await test.sendQuery('non'); + const media = test.getMedia(); +// fs.writeFileSync('/tmp/media.json', JSON.stringify(media)); + chai.expect(media).to.deep.equal({ + "optionalMediaControls": [ + "PAUSED", + "STOPPED" + ], + "mediaObjects": [ + { + "name": "Thérèse Raquin - 1", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap01-03.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 2", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap04-06.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 3", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap07-09.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 4", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap10-12.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 5", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap13-16.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 6", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap17-18.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 7", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap19-20.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 8", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap21-22.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 9", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap23-25.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 10", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap26-27.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 11", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap28-29.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 12", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap30-32.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + } + ], + "startOffset": { + "seconds": "0", + "nanos": 0 + }, + "mediaType": "AUDIO" + }); + + + + // + // resp = test.getLatestResponse(); + } + + before('before all', async () => { + // Load project settings to read project ID and trigger phrase. + test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); + await test.writePreviewFromDraft(); + test.setSuiteLocale(DEFAULT_LOCALE); + test.setSuiteSurface(DEFAULT_SURFACE); + }); + + afterEach('post test cleans', async () => { + test.cleanUpAfterTest(); + }); + + it('search with bad query', async () => { + await startConversation(); + await test.sendQuery("quitter"); + // test.assertConversationEnded(); + }); +}); diff --git a/test/dev/test/test7.ts b/test/dev/test/test7.ts new file mode 100644 index 00000000..35836d0f --- /dev/null +++ b/test/dev/test/test7.ts @@ -0,0 +1,254 @@ +import 'mocha'; + +import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; +import {ok} from 'assert'; +import { inspect } from 'util'; +import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; +import * as chai from 'chai'; + +const TEST_NUM = 7; +import * as fs from 'fs'; + +describe('My Action Test Suite', function () { + // Set the timeout for each test run to 60s. + this.timeout(60000); + let test: ActionsOnGoogleTestManager; + + async function startConversation() { + await test.sendQuery(TRIGGER_PHRASE); + test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertIntent('actions.intent.MAIN'); + test.assertScene('home_members_lvl2'); + + await test.sendQuery(`setup test ${TEST_NUM}`); + test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); + + // 123 : player therese_raquin_emile_zola.json + await test.sendQuery(`test player 123`); + test.assertSpeech(`test player 123 ${MEMBER_PROMPT}`); + + // RECHERCHE + + await test.sendQuery('lecture'); + test.assertSpeech(`Voulez-vous reprendre la lecture là où elle s'était arrêtée `); + + await test.sendQuery('test'); + const resp = test.getLatestResponse(); + chai.expect(test.getSpeech()).to.equal("je n'ai pas compris. Que voulez-vous dire ?"); + test.assertSpeech("je n'ai pas compris. Que voulez-vous dire ?"); + + let media = test.getMedia(); + chai.expect(media).to.equal(undefined); + + await test.sendQuery('non'); + + + media = test.getMedia(); +// fs.writeFileSync('/tmp/media.json', JSON.stringify(media)); + chai.expect(media).to.deep.equal({ + "optionalMediaControls": [ + "PAUSED", + "STOPPED" + ], + "mediaObjects": [ + { + "name": "Thérèse Raquin - 1", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap01-03.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 2", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap04-06.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 3", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap07-09.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 4", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap10-12.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 5", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap13-16.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 6", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap17-18.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 7", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap19-20.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 8", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap21-22.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 9", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap23-25.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 10", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap26-27.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 11", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap28-29.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 12", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap30-32.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + } + ], + "startOffset": { + "seconds": "0", + "nanos": 0 + }, + "mediaType": "AUDIO" + }); + + + + // + // resp = test.getLatestResponse(); + } + + before('before all', async () => { + // Load project settings to read project ID and trigger phrase. + test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); + await test.writePreviewFromDraft(); + test.setSuiteLocale(DEFAULT_LOCALE); + test.setSuiteSurface(DEFAULT_SURFACE); + }); + + afterEach('post test cleans', async () => { + test.cleanUpAfterTest(); + }); + + it('search with bad query', async () => { + await startConversation(); + await test.sendQuery("quitter"); + // test.assertConversationEnded(); + }); +}); diff --git a/test/dev/test/test8.ts b/test/dev/test/test8.ts new file mode 100644 index 00000000..abe72c68 --- /dev/null +++ b/test/dev/test/test8.ts @@ -0,0 +1,432 @@ +import 'mocha'; + +import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; +import {ok} from 'assert'; +import { inspect } from 'util'; +import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; +import * as chai from 'chai'; + +const TEST_NUM = 8; +import * as fs from 'fs'; + +describe('player resume listening | repprendre la lecture', function () { + // Set the timeout for each test run to 60s. + this.timeout(60000); + let test: ActionsOnGoogleTestManager; + + async function startConversation() { + await test.sendQuery(TRIGGER_PHRASE); + test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertIntent('actions.intent.MAIN'); + test.assertScene('home_members_lvl2'); + + await test.sendQuery(`setup test ${TEST_NUM}`); + test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); + + // 123 : player therese_raquin_emile_zola.json + await test.sendQuery(`test player 123`); + test.assertSpeech(`test player 123 ${MEMBER_PROMPT}`); + + // RECHERCHE + + await test.sendQuery('lecture'); + test.assertSpeech(`Voulez-vous reprendre la lecture là où elle s'était arrêtée `); + + await test.sendQuery('non'); + + let media = test.getMedia(); +// fs.writeFileSync('/tmp/media.json', JSON.stringify(media)); + chai.expect(media).to.deep.equal({ + "optionalMediaControls": [ + "PAUSED", + "STOPPED" + ], + "mediaObjects": [ + { + "name": "Thérèse Raquin - 1", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap01-03.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 2", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap04-06.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 3", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap07-09.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 4", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap10-12.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 5", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap13-16.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 6", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap17-18.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 7", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap19-20.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 8", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap21-22.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 9", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap23-25.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 10", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap26-27.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 11", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap28-29.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 12", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap30-32.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + } + ], + "startOffset": { + "seconds": "0", + "nanos": 0 + }, + "mediaType": "AUDIO" + }); + + await test.sendQuery('reprend la lecture'); + + media = test.getMedia(); + // console.log(media); + // + // same + chai.expect(media).to.deep.equal({ + "optionalMediaControls": [ + "PAUSED", + "STOPPED" + ], + "mediaObjects": [ + { + "name": "Thérèse Raquin - 1", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap01-03.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 2", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap04-06.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 3", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap07-09.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 4", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap10-12.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 5", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap13-16.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 6", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap17-18.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 7", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap19-20.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 8", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap21-22.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 9", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap23-25.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 10", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap26-27.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 11", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap28-29.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 12", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap30-32.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + } + ], + "startOffset": { + "seconds": "0", + "nanos": 0 + }, + "mediaType": "AUDIO" + }); + + + // + // resp = test.getLatestResponse(); + } + + before('before all', async () => { + // Load project settings to read project ID and trigger phrase. + test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); + await test.writePreviewFromDraft(); + test.setSuiteLocale(DEFAULT_LOCALE); + test.setSuiteSurface(DEFAULT_SURFACE); + }); + + afterEach('post test cleans', async () => { + test.cleanUpAfterTest(); + }); + + it('search with bad query', async () => { + await startConversation(); + await test.sendQuery("quitter"); + // test.assertConversationEnded(); + }); +}); From 827f62e9b4f90236e0e3ac6be56a82d2c4646ebe Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 3 Nov 2021 16:30:04 +0100 Subject: [PATCH 011/180] test: selections --- test/dev/test/test10.ts | 55 +++++++++++++++++++++++++++++++++++++++++ test/dev/test/test11.ts | 55 +++++++++++++++++++++++++++++++++++++++++ test/dev/test/test8.ts | 4 +-- test/dev/test/test9.ts | 55 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 test/dev/test/test10.ts create mode 100644 test/dev/test/test11.ts create mode 100644 test/dev/test/test9.ts diff --git a/test/dev/test/test10.ts b/test/dev/test/test10.ts new file mode 100644 index 00000000..20d2ee7f --- /dev/null +++ b/test/dev/test/test10.ts @@ -0,0 +1,55 @@ +import 'mocha'; + +import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; +import {ok} from 'assert'; +import { inspect } from 'util'; +import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; +import * as chai from 'chai'; + +const TEST_NUM = 9; +import * as fs from 'fs'; + +describe('My Action Test Suite', function () { + // Set the timeout for each test run to 60s. + this.timeout(60000); + let test: ActionsOnGoogleTestManager; + + async function startConversation() { + await test.sendQuery(TRIGGER_PHRASE); + test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertIntent('actions.intent.MAIN'); + test.assertScene('home_members_lvl2'); + + await test.sendQuery(`setup test ${TEST_NUM}`); + test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); + + + await test.sendQuery(`sélections`); + test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre, Que voulez-vous faire ?`); + + await test.sendQuery(`selections thématiques`); + + + // + // resp = test.getLatestResponse(); + } + + before('before all', async () => { + // Load project settings to read project ID and trigger phrase. + test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); + await test.writePreviewFromDraft(); + test.setSuiteLocale(DEFAULT_LOCALE); + test.setSuiteSurface(DEFAULT_SURFACE); + }); + + afterEach('post test cleans', async () => { + test.cleanUpAfterTest(); + }); + + it('thematic selection', async () => { + await startConversation(); + await test.sendQuery("quitter"); + // test.assertConversationEnded(); + }); +}); diff --git a/test/dev/test/test11.ts b/test/dev/test/test11.ts new file mode 100644 index 00000000..b34cb219 --- /dev/null +++ b/test/dev/test/test11.ts @@ -0,0 +1,55 @@ +import 'mocha'; + +import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; +import {ok} from 'assert'; +import { inspect } from 'util'; +import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; +import * as chai from 'chai'; + +const TEST_NUM = 9; +import * as fs from 'fs'; + +describe('My Action Test Suite', function () { + // Set the timeout for each test run to 60s. + this.timeout(60000); + let test: ActionsOnGoogleTestManager; + + async function startConversation() { + await test.sendQuery(TRIGGER_PHRASE); + test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertIntent('actions.intent.MAIN'); + test.assertScene('home_members_lvl2'); + + await test.sendQuery(`setup test ${TEST_NUM}`); + test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); + + + await test.sendQuery(`sélections`); + test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre, Que voulez-vous faire ?`); + + await test.sendQuery(`selections par genre`); + + + // + // resp = test.getLatestResponse(); + } + + before('before all', async () => { + // Load project settings to read project ID and trigger phrase. + test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); + await test.writePreviewFromDraft(); + test.setSuiteLocale(DEFAULT_LOCALE); + test.setSuiteSurface(DEFAULT_SURFACE); + }); + + afterEach('post test cleans', async () => { + test.cleanUpAfterTest(); + }); + + it('genre selection', async () => { + await startConversation(); + await test.sendQuery("quitter"); + // test.assertConversationEnded(); + }); +}); diff --git a/test/dev/test/test8.ts b/test/dev/test/test8.ts index abe72c68..1fa173db 100644 --- a/test/dev/test/test8.ts +++ b/test/dev/test/test8.ts @@ -9,7 +9,7 @@ import * as chai from 'chai'; const TEST_NUM = 8; import * as fs from 'fs'; -describe('player resume listening | repprendre la lecture', function () { +describe('My Action Test Suite', function () { // Set the timeout for each test run to 60s. this.timeout(60000); let test: ActionsOnGoogleTestManager; @@ -424,7 +424,7 @@ describe('player resume listening | repprendre la lecture', function () { test.cleanUpAfterTest(); }); - it('search with bad query', async () => { + it('player resume listening | repprendre la lecture', async () => { await startConversation(); await test.sendQuery("quitter"); // test.assertConversationEnded(); diff --git a/test/dev/test/test9.ts b/test/dev/test/test9.ts new file mode 100644 index 00000000..7fcd9ca1 --- /dev/null +++ b/test/dev/test/test9.ts @@ -0,0 +1,55 @@ +import 'mocha'; + +import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; +import {ok} from 'assert'; +import { inspect } from 'util'; +import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; +import * as chai from 'chai'; + +const TEST_NUM = 9; +import * as fs from 'fs'; + +describe('My Action Test Suite', function () { + // Set the timeout for each test run to 60s. + this.timeout(60000); + let test: ActionsOnGoogleTestManager; + + async function startConversation() { + await test.sendQuery(TRIGGER_PHRASE); + test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertIntent('actions.intent.MAIN'); + test.assertScene('home_members_lvl2'); + + await test.sendQuery(`setup test ${TEST_NUM}`); + test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); + + + await test.sendQuery(`sélections`); + test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre, Que voulez-vous faire ?`); + + await test.sendQuery(`ma liste`); + + + // + // resp = test.getLatestResponse(); + } + + before('before all', async () => { + // Load project settings to read project ID and trigger phrase. + test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); + await test.writePreviewFromDraft(); + test.setSuiteLocale(DEFAULT_LOCALE); + test.setSuiteSurface(DEFAULT_SURFACE); + }); + + afterEach('post test cleans', async () => { + test.cleanUpAfterTest(); + }); + + it('my list', async () => { + await startConversation(); + await test.sendQuery("quitter"); + // test.assertConversationEnded(); + }); +}); From 886e400919f240996fd276ecca41f416466767ea Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 3 Nov 2021 16:59:42 +0100 Subject: [PATCH 012/180] webhooks: switch to typescript --- webhooks/functions/build/index.js | 503 ++++++++++++++++++ webhooks/functions/build/index.js.map | 1 + webhooks/functions/package-lock.json | 6 + webhooks/functions/package.json | 8 +- webhooks/functions/{index.js => src/index.ts} | 32 +- webhooks/functions/tsconfig.json | 17 + 6 files changed, 549 insertions(+), 18 deletions(-) create mode 100644 webhooks/functions/build/index.js create mode 100644 webhooks/functions/build/index.js.map rename webhooks/functions/{index.js => src/index.ts} (94%) create mode 100644 webhooks/functions/tsconfig.json diff --git a/webhooks/functions/build/index.js b/webhooks/functions/build/index.js new file mode 100644 index 00000000..02a8073e --- /dev/null +++ b/webhooks/functions/build/index.js @@ -0,0 +1,503 @@ +const { conversation, Media } = require("@assistant/conversation"); +const functions = require("firebase-functions"); +const admin = require("firebase-admin"); +admin.initializeApp(); +const db = admin.firestore(); +const { OpdsFetcher } = require("opds-fetcher-parser"); +const { ok } = require("assert"); +const app = conversation(); +const appHandle = app.handle.bind(app); +app.handle = (path, fn) => { + appHandle(path, async (conv) => { + let pass = false; + try { + const id = conv.user.params.bearerToken; + ok(id, "bearerToken not defined"); + const docRef = db.collection("user-storage").doc(id); + await Promise.resolve(fn(conv)); + pass = true; + await docRef.set(conv.user.params); + } + catch (e) { + console.error(e); + if (!pass) + await Promise.resolve(fn(conv)); + } + }); +}; +function isValidHttpUrl(string) { + let url; + try { + url = new URL(string); + } + catch (_) { + return false; + } + return url.protocol === "http:" || url.protocol === "https:"; +} +async function getPubsFromFeed(url) { + const opds = new OpdsFetcher(); + const feed = await opds.feedRequest(url); + ok(Array.isArray(feed.publications), "no publications"); + const list = feed.publications + .filter(({ openAccessLinks: l }) => { + return (Array.isArray(l) && + l[0] && + isValidHttpUrl(l[0].url)); + }) + .slice(0, 5) + .map(({ title, authors, openAccessLinks }) => ({ + title: title, + author: Array.isArray(authors) ? authors[0].name : "", + webpuburl: openAccessLinks[0].url, + })); + return list; +} +////////// +// TEST // +////////// +app.handle("test_player_sdk", (conv) => { + const nb = conv.intent.params.number.resolved; + switch (nb) { + case 123: + conv.user.params = { + ...conv.user.params, + p_i: 2, + p_n: "therese_raquin_emile_zola.json", + p_t: 123, + player: { + ...conv.user.params.player || {}, + ["therese_raquin_emile_zola.json"]: { + p_i: 2, + p_n: "therese_raquin_emile_zola.json", + p_t: 123, + }, + }, + }; + break; + case 456: + break; + case 789: + break; + } + console.log("test_PLAYER"); + console.log(conv.user.params); + conv.add(`test player ${nb}`); +}); +app.handle("setup_test_sdk", (conv) => { + const nb = conv.intent.params.number.resolved; + conv.user.params = { + bearerToken: `test-${nb}`, + }; + conv.add(`setup test ${nb}`); +}); +////////// +// TEST // +////////// +// ---------------- +// +// CONVERSATION START +// +// ---------------- +app.handle("cancel", (conv) => { + // Implement your code here + // conv.add("cancel"); +}); +app.handle("test_webhook", (conv) => { + conv.add("Webook works :", functions.config().debug.message || ""); + console.log("TEST OK"); +}); +// ----------- +// LVL2 MENU +// SELECTION +// ----------- +const WEBPUB_URL = "https://storage.googleapis.com/audiobook_edrlab/webpub/"; +const extract_name_from_url = (url) => { + const name = /\/(?:.(?!\/))+$/.exec(url)[0]; + if (typeof name === "string") + return name.slice(1); + return ""; +}; +// ----------- +// LVL3 MENU +// SELECTION +// ----------- +app.handle("selection_genre_lvl3", async (conv) => { + conv.add("sélection par genre"); +}); +app.handle("selection_thematic_list_lvl3", async (conv) => { + conv.add("sélection par liste thématique"); +}); +const SELECTION_URL = "https://storage.googleapis.com/audiobook_edrlab/groups/popular.json"; +app.handle("selection_my_list_lvl3", async (conv) => { + const url = SELECTION_URL; + const list = await getPubsFromFeed(url); + console.log("PUBs: ", list); + const length = list.length; + if (length > 1) { + conv.scene.next.name = "select_pub_after_selection"; + conv.add(`Il y a ${length} publications :\n`); + let text = ""; + list.map(({ title, author }, i) => { + text += `numero ${i + 1} : ${title} ${author ? `de ${author}` : ""}\n`; + }); + conv.add(text); + } + else if (length === 1) { + conv.scene.next.name = "ask_to_resume_listening_at_last_offset"; + conv.user.params.p_n = extract_name_from_url(list[0].webpuburl); + } + else { + conv.scene.next.name = "home_members"; + conv.add("aucun résultat trouvé"); + } + console.log("selection_my_list_lvl3 EXIT"); +}); +// --------- +// LVL3 MENU +// SELECTION +// --------- +app.handle("select_publication_number_after_selection", async (conv) => { + console.log("select_publication_number START"); + const number = conv.intent.params.number.resolved; + const url = SELECTION_URL; + const list = await getPubsFromFeed(url); + const pub = list[number - 1]; + if (pub) { + console.log("PUB: ", pub); + const url = extract_name_from_url(pub.webpuburl); + if (!conv.user.params.player) { + conv.user.params.player = {}; + } + const history = conv.user.params.player[url]; + if (!history) { + conv.user.params.p_i = 0; + conv.user.params.p_t = 0; + } + else { + conv.user.params.p_i = history.i; + conv.user.params.p_t = history.t; + } + conv.user.params.p_n = url; + // should be specified + conv.scene.next.name = "ask_to_resume_listening_at_last_offset"; + } + else { + console.log("NO PUBS found !!"); + conv.add(`Le numéro ${number} est inconnu. Veuillez choisir un autre numéro.`); + conv.scene.next.name = "select_pub_after_selection"; + } + console.log("select_publication_number END"); +}); +// ----------- +// LVL2 MENU +// SELECTION +// ----------- +app.handle("reprendre_mon_livre_lvl2", (conv) => { + // void + const name = conv.user.params.p_n; + if (!name) { + conv.scene.next.name = "home_members"; + conv.add("aucune lecture en cours"); + } +}); +app.handle("ecouter_livre_audio_lvl2", (conv) => { + // void + console.log("écouter_livre_audio_lvl2"); + // first entry point for search + // + // VOID + // + // search_livre_lvl2 is the main entry point +}); +// ---------- +// LVL2 MENU +// SEARCH +// ---------- +const SEARCH_URL = "https://europe-west1-audiobooks-a6348.cloudfunctions.net/indexer?url=https://storage.googleapis.com/audiobook_edrlab/navigation/all.json&query={query}"; +// if scene.slot.status == "FINAL" => call search_livre_lvl2 +app.handle("search_livre_lvl2", async (conv) => { + // void + console.log("search_livre_lvl2 START"); + let query = null; + try { + query = conv.intent.params.query.resolved; + } + catch (_) { + // ignore + } + ok(typeof query === "string", "aucune requete demandée"); + conv.session.params.query = query; + const url = SEARCH_URL.replace("{query}", encodeURIComponent(query)); + console.log("search URL: ", url); + const list = await getPubsFromFeed(url); + console.log("PUBs: "); + console.log(list); + const length = list.length; + if (length > 1) { + conv.scene.next.name = "select_pub_after_search"; + conv.add(`Il y a ${length} publications :\n`); + let text = ""; + list.map(({ title, author }, i) => { + text += `numero ${i + 1} : ${title} ${author ? `de ${author}` : ""}\n`; + }); + conv.add(text); + } + else if (length === 1) { + conv.scene.next.name = "ask_to_resume_listening_at_last_offset"; + conv.user.params.p_n = extract_name_from_url(list[0].webpuburl); + } + else { + conv.scene.next.name = "search"; + conv.add("aucun résultat trouvé"); + } + console.log("search_livre_lvl2 STOP"); + // slot available for research +}); +app.handle("select_publication_number_after_search", async (conv) => { + console.log("select_publication_number START"); + const number = conv.intent.params.number.resolved; + console.log("NUMBER: ", number); + const query = conv.session.params.query; + ok(typeof query === "string", "aucune requete demandée"); + const url = SEARCH_URL.replace("{query}", encodeURIComponent(query)); + console.log("select_publication_number_after_search URL: ", url); + const list = await getPubsFromFeed(url); + const pub = list[number - 1]; + if (pub) { + console.log("PUB: ", pub); + const name = extract_name_from_url(pub.webpuburl); + if (!conv.user.params.player) { + conv.user.params.player = {}; + } + const history = conv.user.params.player[name]; + if (!history) { + conv.user.params.p_i = 0; + conv.user.params.p_t = 0; + } + else { + conv.user.params.p_i = history.i; + conv.user.params.p_t = history.t; + } + conv.user.params.p_n = name; + // should be specified + conv.scene.next.name = "ask_to_resume_listening_at_last_offset"; + } + else { + console.log("NO PUBS found !!"); + conv.add(`Le numéro ${number} est inconnu. Veuillez choisir un autre numéro.`); + conv.scene.next.name = "select_pub_after_search"; + } + console.log("select_publication_number END"); +}); +// ---------- +// LVL2 MENU +// SEARCH +// ---------- +app.handle("ask_to_resume_listening_at_last_offset", async (conv) => { + const { p_n: name, p_i, p_t } = conv.user.params; + if (name && (p_i > 0 || p_t > 0)) { + console.log("ask to resume enabled , wait yes or no"); + // ask yes or no in the no-code scene + const history = conv.user.params.player[name]; + const date = history.d; + // TODO: use the date info + conv.add("Voulez-vous reprendre la lecture là où elle s'était arrêtée ?"); + } + else { + console.log("no need to ask to resume"); + conv.scene.next.name = "player"; + } +}); +app.handle("ask_to_resume_listening_at_last_offset__yes", async (conv) => { + // nothing + // not used + conv.scene.next.name = "player"; +}); +app.handle("ask_to_resume_listening_at_last_offset__no", async (conv) => { + const name = conv.user.params.p_n; + if (name) { + console.log("erase ", name, " resume listening NO"); + conv.user.params.p_i = 0; + conv.user.params.p_t = 0; + } + conv.scene.next.name = "player"; +}); +// ---------- +// PLAYER +// ---------- +app.handle("player", async (conv) => { + const name = conv.user.params.p_n; + const url = WEBPUB_URL + name; + console.log("Player URL:", url); + ok(url, "url not defined"); + ok(isValidHttpUrl(url), "url not valid " + url); + const opds = new OpdsFetcher(); + const webpub = await opds.webpubRequest(url); + ok(webpub, "webpub not defined"); + const startIndexRaw = conv.user.params.p_i; + const startIndex = typeof startIndexRaw === "number" && + startIndexRaw <= webpub.readingOrders.length ? startIndexRaw : 0; + const startTimeRaw = conv.user.params.p_t; + const startTime = typeof startTimeRaw === "number" && + startTimeRaw <= (webpub.readingOrders[startIndex].duration || Infinity) ? startTimeRaw : 0; + const mediaObjects = webpub.readingOrders + .map((v, i) => ({ + name: `${webpub.title || ""} - ${i + 1}`, + url: v.url, + image: { + large: { + alt: webpub.title, + url: webpub.cover || "", + }, + }, + })).slice(startIndex); + console.log("Media list"); + console.log(mediaObjects); + console.log("Start Index = ", startIndex, " Start Time = ", startTime, " Start Time"); + conv.add(new Media({ + mediaObjects: mediaObjects, + mediaType: "AUDIO", + optionalMediaControls: ["PAUSED", "STOPPED"], + startOffset: `${startTime}s`, + })); +}); +// ---------- +// PLAYER +// ---------- +// //////////////////////// +// Media PLAYET CONTEXT // +// //////////////////////// +function persistMediaPlayer(conv) { + if (conv.request.context) { + // Persist the media progress value + const progress = parseInt(conv.request.context.media.progress, 10); + const index = conv.request.context.media.index; + const name = conv.user.params.p_n; + conv.user.params.p_i = index; + conv.user.params.p_t = progress; + if (!conv.user.params.player) { + conv.user.params.player = {}; + } + conv.user.params.player[name] = { + i: index, + t: progress, + d: new Date().getTime(), + }; + console.log("player persistence :"); + console.log(conv.user.params.player); + } + else { + console.log("NO conv.request.context !!"); + } +} +app.handle("reprendre_la_lecture", (conv) => { + persistMediaPlayer(conv); + // // Acknowledge pause/stop + // conv.add(new Media({ + // mediaType: 'MEDIA_STATUS_ACK' + // })); + conv.scene.next.name = "player"; +}); +app.handle("remaining_time", async (conv) => { + persistMediaPlayer(conv); + const name = conv.user.params.p_n; + ok(name, "titre non défini"); + const url = WEBPUB_URL + name; + ok(isValidHttpUrl(url), "url not valid " + url); + const opds = new OpdsFetcher(); + const webpub = await opds.webpubRequest(url); + ok(webpub, "webpub not defined"); + const index = conv.user.params.player_startIndex || 0; + const time = conv.user.params.player_startTime || 0; + let minutes = 0; + if (Array.isArray(webpub.readingOrders)) { + let remainingTime = 0; + for (let i = index + 1; i < webpub.readingOrders.length; i += 1) { + remainingTime += webpub.readingOrders[i].duration || 0; + } + const pos = (v) => (v < 0 ? 0 : v); + remainingTime += pos((webpub.readingOrders[index].duration || 0) - time); + if (remainingTime >= 60) { + minutes = Math.floor(remainingTime / 60); + } + } + const hours = Math.floor(minutes / 60); + if (hours) { + minutes = minutes % 60; + conv.add(`il reste ${hours} heures et ${minutes} minutes`); + } + else { + conv.add(`il reste ${minutes} minutes`); + } + // // Acknowledge pause/stop + // conv.add(new Media({ + // mediaType: 'MEDIA_STATUS_ACK' + // })); + conv.scene.next.name = "player"; +}); +// //////////////////////// +// Media PLAYET CONTEXT // +// //////////////////////// +// Media status +app.handle("media_status", (conv) => { + console.log("MediaStatus START"); + const mediaStatus = conv.intent.params.MEDIA_STATUS.resolved; + console.log("MediaStatus : ", mediaStatus); + switch (mediaStatus) { + case "FINISHED": + persistMediaPlayer(conv); + conv.scene.next.name = "home_members"; + // void + break; + case "FAILED": + // void + break; + case "PAUSED": + case "STOPPED": + persistMediaPlayer(conv); + // Acknowledge pause/stop + conv.add(new Media({ + mediaType: "MEDIA_STATUS_ACK", + })); + break; + default: + conv.add("media status incorrect"); + } + console.log("MediaStatus END"); +}); +// catch(catcher: ExceptionHandler): ConversationV3App +// ExceptionHandler(conv: TConversation, error: Error): any +app.catch((conv, error) => { + conv.add("une erreur s'est produite"); + console.log("ERROR"); + console.log(error); +}); +// middleware(middleware: ConversationV3Middleware): ConversationV3App +// ConversationV3Middleware(conv: ConversationV3, framework: BuiltinFrameworkMetadata): void | ConversationV3 & TConversationPlugin | Promise | Promise +app.middleware(async (conv) => { + console.log(conv.user.params); + console.log("=========="); + console.log(conv); + console.log("----------"); + try { + const id = conv.user.params.bearerToken; + ok(id, "bearerToken not defined"); + const docRef = db.collection("user-storage").doc(id); + const doc = await docRef.get(); + if (!doc.exists) { + console.log("No such document!"); + } + else { + console.log("Document data:", doc.data()); + conv.user.params = doc.data(); + } + } + catch (e) { + console.error("Middleware critical error firebase firestore"); + console.error(e); + } + // void +}); +exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/webhooks/functions/build/index.js.map b/webhooks/functions/build/index.js.map new file mode 100644 index 00000000..ae545398 --- /dev/null +++ b/webhooks/functions/build/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,EAAC,YAAY,EAAE,KAAK,EAAC,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;AACjE,MAAM,SAAS,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAChD,MAAM,KAAK,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAExC,KAAK,CAAC,aAAa,EAAE,CAAC;AAEtB,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;AAE7B,MAAM,EAAC,WAAW,EAAC,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;AACrD,MAAM,EAAC,EAAE,EAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE/B,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;AAE3B,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEvC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE;IAExB,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAE7B,IAAI,IAAI,GAAG,KAAK,CAAC;QACjB,IAAI;YAEF,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;YAExC,EAAE,CAAC,EAAE,EAAE,yBAAyB,CAAC,CAAC;YAElC,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACrD,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;YAChC,IAAI,GAAG,IAAI,CAAC;YACZ,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SAEpC;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACjB,IAAI,CAAC,IAAI;gBACP,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;SAEnC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,SAAS,cAAc,CAAC,MAAM;IAC5B,IAAI,GAAG,CAAC;IAER,IAAI;QACF,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;KACvB;IAAC,OAAO,CAAC,EAAE;QACV,OAAO,KAAK,CAAC;KACd;IAED,OAAO,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC;AAC/D,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,GAAG;IAEhC,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAEzC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,iBAAiB,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY;SACzB,MAAM,CAAC,CAAC,EAAC,eAAe,EAAE,CAAC,EAAC,EAA8B,EAAE;QAC3D,OAAO,CACL,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC,CAAC;YACJ,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CACvB,CAAC;IACJ,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,EAAC,KAAK,EAAE,OAAO,EAAE,eAAe,EAAC,EAAE,EAAE,CAAC,CAAC;QAC3C,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;QACrD,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG;KAClC,CAAC,CAAC,CAAC;IAER,OAAO,IAAI,CAAC;AACd,CAAC;AAED,UAAU;AACV,UAAU;AACV,UAAU;AAEV,GAAG,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,IAAI,EAAE,EAAE;IAErC,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;IAE9C,QAAQ,EAAE,EAAE;QAEV,KAAK,GAAG;YAEN,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG;gBACjB,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM;gBACnB,GAAG,EAAE,CAAC;gBACN,GAAG,EAAE,gCAAgC;gBACrC,GAAG,EAAE,GAAG;gBACR,MAAM,EAAE;oBACN,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE;oBAChC,CAAC,gCAAgC,CAAC,EAAE;wBAClC,GAAG,EAAE,CAAC;wBACN,GAAG,EAAE,gCAAgC;wBACrC,GAAG,EAAE,GAAG;qBACT;iBACF;aACF,CAAC;YAEF,MAAM;QAER,KAAK,GAAG;YAEN,MAAM;QACR,KAAK,GAAG;YAEN,MAAM;KACT;IAED,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC3B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE9B,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,IAAI,EAAE,EAAE;IAEpC,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;IAE9C,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG;QACjB,WAAW,EAAE,QAAQ,EAAE,EAAE;KAC1B,CAAA;IAED,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;AAE/B,CAAC,CAAC,CAAC;AAEH,UAAU;AACV,UAAU;AACV,UAAU;AAEV,mBAAmB;AACnB,EAAE;AACF,qBAAqB;AACrB,EAAE;AACF,mBAAmB;AAEnB,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;IAC5B,2BAA2B;IAC3B,sBAAsB;AACxB,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE;IAElC,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AACzB,CAAC,CAAC,CAAC;AAEH,cAAc;AACd,YAAY;AACZ,aAAa;AACb,cAAc;AAGd,MAAM,UAAU,GAAG,yDAAyD,CAAC;AAE7E,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE,EAAE;IAEpC,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAE5C,IAAI,OAAO,IAAI,KAAK,QAAQ;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEvB,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC;AAEF,cAAc;AACd,YAAY;AACZ,YAAY;AACZ,cAAc;AAEd,GAAG,CAAC,MAAM,CAAC,sBAAsB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAEhD,IAAI,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;AAClC,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,MAAM,CAAC,8BAA8B,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAExD,IAAI,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;AAC7C,CAAC,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG,qEAAqE,CAAA;AAC3F,GAAG,CAAC,MAAM,CAAC,wBAAwB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAElD,MAAM,GAAG,GAAG,aAAa,CAAC;IAC1B,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAE5B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC3B,IAAI,MAAM,GAAG,CAAC,EAAE;QACd,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;QACpD,IAAI,CAAC,GAAG,CAAC,UAAU,MAAM,mBAAmB,CAAC,CAAC;QAE9C,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,IAAI,CAAC,GAAG,CAAC,CAAC,EAAC,KAAK,EAAE,MAAM,EAAC,EAAE,CAAC,EAAE,EAAE;YAC9B,IAAI,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;QACzE,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;KAChB;SAAM,IAAI,MAAM,KAAK,CAAC,EAAE;QACvB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,wCAAwC,CAAC;QAEhE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;KACjE;SAAM;QACL,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAEtC,IAAI,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;KACnC;IAED,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;AAE7C,CAAC,CAAC,CAAC;AAEH,YAAY;AACZ,YAAY;AACZ,YAAY;AACZ,YAAY;AAEZ,GAAG,CAAC,MAAM,CAAC,2CAA2C,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IACrE,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAE/C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;IAElD,MAAM,GAAG,GAAG,aAAa,CAAC;IAC1B,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7B,IAAI,GAAG,EAAE;QACP,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAE1B,MAAM,GAAG,GAAG,qBAAqB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAEjD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;YAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;SAC9B;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,EAAE;YACZ,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;SAC1B;aAAM;YACL,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC;SAClC;QACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC;QAE3B,sBAAsB;QACtB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,wCAAwC,CAAC;KACjE;SAAM;QACL,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,aAAa,MAAM,iDAAiD,CAAC,CAAC;QAC/E,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;KACrD;IAED,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;AAC/C,CAAC,CAAC,CAAC;AAGH,cAAc;AACd,YAAY;AACZ,aAAa;AACb,cAAc;AAEd,GAAG,CAAC,MAAM,CAAC,0BAA0B,EAAE,CAAC,IAAI,EAAE,EAAE;IAE9C,OAAO;IAEP,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IAClC,IAAI,CAAC,IAAI,EAAE;QACT,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QACtC,IAAI,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;KACrC;AAEH,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,MAAM,CAAC,0BAA0B,EAAE,CAAC,IAAI,EAAE,EAAE;IAC9C,OAAO;IAEP,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAExC,+BAA+B;IAC/B,EAAE;IACF,OAAO;IACP,EAAE;IACF,4CAA4C;AAC9C,CAAC,CAAC,CAAC;AAGH,aAAa;AACb,YAAY;AACZ,SAAS;AACT,aAAa;AAEb,MAAM,UAAU,GAAG,wJAAwJ,CAAC;AAE5K,4DAA4D;AAC5D,GAAG,CAAC,MAAM,CAAC,mBAAmB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAC7C,OAAO;IAEP,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IAEvC,IAAI,KAAK,GAAG,IAAI,CAAC;IAEjB,IAAI;QACF,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;KAC3C;IAAC,OAAO,CAAC,EAAE;QACV,SAAS;KACV;IAED,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,EAAE,yBAAyB,CAAC,CAAC;IACzD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;IAElC,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,SAAS,EAAE,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IAEjC,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAElB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC3B,IAAI,MAAM,GAAG,CAAC,EAAE;QACd,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;QACjD,IAAI,CAAC,GAAG,CAAC,UAAU,MAAM,mBAAmB,CAAC,CAAC;QAE9C,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,IAAI,CAAC,GAAG,CAAC,CAAC,EAAC,KAAK,EAAE,MAAM,EAAC,EAAE,CAAC,EAAE,EAAE;YAC9B,IAAI,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;QACzE,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;KAChB;SAAM,IAAI,MAAM,KAAK,CAAC,EAAE;QACvB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,wCAAwC,CAAC;QAEhE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;KACjE;SAAM;QACL,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;QAEhC,IAAI,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;KACnC;IAED,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IAEtC,8BAA8B;AAChC,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,MAAM,CAAC,wCAAwC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAClE,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAE/C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;IAElD,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;IACxC,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,EAAE,yBAAyB,CAAC,CAAC;IAEzD,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,SAAS,EAAE,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,8CAA8C,EAAE,GAAG,CAAC,CAAC;IAEjE,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7B,IAAI,GAAG,EAAE;QACP,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAE1B,MAAM,IAAI,GAAG,qBAAqB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAElD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;YAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;SAC9B;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,EAAE;YACZ,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAE,CAAC,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;SAC1B;aAAM;YACL,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC;SAClC;QACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC;QAE5B,sBAAsB;QACtB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,wCAAwC,CAAC;KACjE;SAAM;QACL,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,aAAa,MAAM,iDAAiD,CAAC,CAAC;QAC/E,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;KAClD;IAED,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;AAC/C,CAAC,CAAC,CAAC;AAGH,aAAa;AACb,YAAY;AACZ,SAAS;AACT,aAAa;AAEb,GAAG,CAAC,MAAM,CAAC,wCAAwC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAElE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IACjD,IAAI,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,EAAE;QAChC,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;QACtD,qCAAqC;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC;QACvB,0BAA0B;QAE1B,IAAI,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;KAC3E;SAAM;QACL,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;KACjC;AAEH,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,MAAM,CAAC,6CAA6C,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAEvE,UAAU;IACV,WAAW;IACX,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;AAElC,CAAC,CAAC,CAAC;AAGH,GAAG,CAAC,MAAM,CAAC,4CAA4C,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAEtE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IAClC,IAAI,IAAI,EAAE;QACR,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,sBAAsB,CAAC,CAAC;QACpD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;KAC1B;IACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;AAElC,CAAC,CAAC,CAAC;AAGH,aAAa;AACb,SAAS;AACT,aAAa;AAEb,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAClC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IAElC,MAAM,GAAG,GAAG,UAAU,GAAG,IAAI,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;IAChC,EAAE,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;IAC3B,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,gBAAgB,GAAG,GAAG,CAAC,CAAC;IAEhD,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAC7C,EAAE,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAEjC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IAC3C,MAAM,UAAU,GACd,OAAO,aAAa,KAAK,QAAQ;QAC/B,aAAa,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IAErE,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IAC1C,MAAM,SAAS,GACb,OAAO,YAAY,KAAK,QAAQ;QAC9B,YAAY,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAE/F,MAAM,YAAY,GAAG,MAAM,CAAC,aAAa;SACpC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACd,IAAI,EAAE,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE;QACxC,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,KAAK,EAAE;YACL,KAAK,EAAE;gBACL,GAAG,EAAE,MAAM,CAAC,KAAK;gBACjB,GAAG,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;aACxB;SACF;KACF,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAE1B,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC1B,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC1B,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,UAAU,EAAE,gBAAgB,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;IAEtF,IAAI,CAAC,GAAG,CACJ,IAAI,KAAK,CAAC;QACR,YAAY,EAAE,YAAY;QAC1B,SAAS,EAAE,OAAO;QAClB,qBAAqB,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC;QAC5C,WAAW,EAAE,GAAG,SAAS,GAAG;KAC7B,CAAC,CACL,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,aAAa;AACb,SAAS;AACT,aAAa;AAGb,2BAA2B;AAC3B,0BAA0B;AAC1B,2BAA2B;AAE3B,SAAS,kBAAkB,CAAC,IAAI;IAC9B,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;QACxB,mCAAmC;QAEnC,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACnE,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;QAElC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,QAAQ,CAAC;QAEhC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;YAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;SAC9B;QAED,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG;YAC9B,CAAC,EAAE,KAAK;YACR,CAAC,EAAE,QAAQ;YACX,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE;SACxB,CAAC;QAEF,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;KACtC;SAAM;QAEL,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;KAC3C;AACH,CAAC;AAED,GAAG,CAAC,MAAM,CAAC,sBAAsB,EAAE,CAAC,IAAI,EAAE,EAAE;IAC1C,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAEzB,4BAA4B;IAC5B,uBAAuB;IACvB,kCAAkC;IAClC,OAAO;IAEP,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;AAClC,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,MAAM,CAAC,gBAAgB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAC1C,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAEzB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IAClC,EAAE,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;IAE7B,MAAM,GAAG,GAAG,UAAU,GAAG,IAAI,CAAC;IAC9B,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,gBAAgB,GAAG,GAAG,CAAC,CAAC;IAEhD,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAC7C,EAAE,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAEjC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,IAAI,CAAC,CAAC;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,IAAI,CAAC,CAAC;IAEpD,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE;QACvC,IAAI,aAAa,GAAG,CAAC,CAAC;QACtB,KAAK,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;YAC/D,aAAa,IAAI,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC;SACxD;QACD,MAAM,GAAG,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACnC,aAAa,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAEzE,IAAI,aAAa,IAAI,EAAE,EAAE;YACvB,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,EAAE,CAAC,CAAC;SAC1C;KACF;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACvC,IAAI,KAAK,EAAE;QACT,OAAO,GAAG,OAAO,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,GAAG,CAAC,YAAY,KAAK,cAAc,OAAO,UAAU,CAAC,CAAC;KAC5D;SAAM;QACL,IAAI,CAAC,GAAG,CAAC,YAAY,OAAO,UAAU,CAAC,CAAC;KACzC;IAED,4BAA4B;IAC5B,uBAAuB;IACvB,kCAAkC;IAClC,OAAO;IAEP,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;AAClC,CAAC,CAAC,CAAC;AAEH,2BAA2B;AAC3B,0BAA0B;AAC1B,2BAA2B;AAE3B,eAAe;AACf,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE;IAClC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACjC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;IAC3C,QAAQ,WAAW,EAAE;QACnB,KAAK,UAAU;YACb,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;YAEtC,OAAO;YACP,MAAM;QACR,KAAK,QAAQ;YAEX,OAAO;YACP,MAAM;QACR,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS;YACZ,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACzB,yBAAyB;YACzB,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC;gBACjB,SAAS,EAAE,kBAAkB;aAC9B,CAAC,CAAC,CAAC;YACJ,MAAM;QACR;YACE,IAAI,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;KACtC;IAED,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;AACjC,CAAC,CAAC,CAAC;AAGH,oFAAoF;AACpF,2DAA2D;AAC3D,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;IACxB,IAAI,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IAEtC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACrB,CAAC,CAAC,CAAC;AAEH,+HAA+H;AAC/H,mMAAmM;AACnM,GAAG,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IAE5B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC1B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClB,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAE1B,IAAI;QAEF,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;QACxC,EAAE,CAAC,EAAE,EAAE,yBAAyB,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACrD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE;YACf,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;SAClC;aAAM;YACL,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;YAC1C,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;SAC/B;KACF;IAAC,OAAO,CAAC,EAAE;QAEV,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAC9D,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAClB;IAED,OAAO;AACT,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC"} \ No newline at end of file diff --git a/webhooks/functions/package-lock.json b/webhooks/functions/package-lock.json index 4901e0a5..b20f5e9b 100644 --- a/webhooks/functions/package-lock.json +++ b/webhooks/functions/package-lock.json @@ -2467,6 +2467,12 @@ "is-typedarray": "^1.0.0" } }, + "typescript": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", + "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "dev": true + }, "unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index 2c2886ef..951a296a 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -6,12 +6,13 @@ "shell": "firebase functions:shell", "start": "npm run shell", "deploy": "firebase deploy --only functions", - "logs": "firebase functions:log" + "logs": "firebase functions:log", + "build": "tsc" }, "engines": { "node": "14" }, - "main": "index.js", + "main": "build/index.js", "dependencies": { "@assistant/conversation": "^3.0.0", "firebase-admin": "^9.8.0", @@ -19,7 +20,8 @@ "opds-fetcher-parser": "github:panaC/opds_fetcher_parser#efec695f50b386071ccf935396f0a8ea4750c9ae" }, "devDependencies": { - "firebase-functions-test": "^0.2.0" + "firebase-functions-test": "^0.2.0", + "typescript": "^4.4.4" }, "private": true } diff --git a/webhooks/functions/index.js b/webhooks/functions/src/index.ts similarity index 94% rename from webhooks/functions/index.js rename to webhooks/functions/src/index.ts index 193ebbc6..a9db5247 100644 --- a/webhooks/functions/index.js +++ b/webhooks/functions/src/index.ts @@ -1,21 +1,21 @@ -const {conversation, Media} = require("@assistant/conversation"); -const functions = require("firebase-functions"); -const admin = require("firebase-admin"); +import {conversation, ConversationV3, Media} from "@assistant/conversation"; +import * as functions from "firebase-functions"; +import * as admin from "firebase-admin"; +import {OpdsFetcher} from "opds-fetcher-parser"; +import {ok} from "assert"; +import { MediaType, OptionalMediaControl } from "@assistant/conversation/dist/api/schema"; admin.initializeApp(); const db = admin.firestore(); -const {OpdsFetcher} = require("opds-fetcher-parser"); -const {ok} = require("assert"); - const app = conversation(); -const appHandle = app.handle.bind(app); +const appHandle: typeof app.handle = app.handle.bind(app); app.handle = (path, fn) => { - appHandle(path, async (conv) => { + const ret = appHandle(path, async (conv) => { let pass = false; try { @@ -36,9 +36,11 @@ app.handle = (path, fn) => { } }); + + return ret; }; -function isValidHttpUrl(string) { +function isValidHttpUrl(string: string) { let url; try { @@ -50,7 +52,7 @@ function isValidHttpUrl(string) { return url.protocol === "http:" || url.protocol === "https:"; } -async function getPubsFromFeed(url) { +async function getPubsFromFeed(url: string) { const opds = new OpdsFetcher(); const feed = await opds.feedRequest(url); @@ -158,7 +160,7 @@ app.handle("test_webhook", (conv) => { const WEBPUB_URL = "https://storage.googleapis.com/audiobook_edrlab/webpub/"; -const extract_name_from_url = (url) => { +const extract_name_from_url = (url: string) => { const name = /\/(?:.(?!\/))+$/.exec(url)[0]; @@ -483,8 +485,8 @@ app.handle("player", async (conv) => { conv.add( new Media({ mediaObjects: mediaObjects, - mediaType: "AUDIO", - optionalMediaControls: ["PAUSED", "STOPPED"], + mediaType: MediaType.Audio, + optionalMediaControls: [OptionalMediaControl.Paused, OptionalMediaControl.Stopped], startOffset: `${startTime}s`, }), ); @@ -499,7 +501,7 @@ app.handle("player", async (conv) => { // Media PLAYET CONTEXT // // //////////////////////// -function persistMediaPlayer(conv) { +function persistMediaPlayer(conv: ConversationV3) { if (conv.request.context) { // Persist the media progress value @@ -610,7 +612,7 @@ app.handle("media_status", (conv) => { persistMediaPlayer(conv); // Acknowledge pause/stop conv.add(new Media({ - mediaType: "MEDIA_STATUS_ACK", + mediaType: MediaType.MediaStatusACK, })); break; default: diff --git a/webhooks/functions/tsconfig.json b/webhooks/functions/tsconfig.json new file mode 100644 index 00000000..dd0b3ae2 --- /dev/null +++ b/webhooks/functions/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "noImplicitAny": false, + "noEmitOnError": true, + "removeComments": false, + "sourceMap": true, + "target": "ES2020", + "lib": ["ES2020"], + "module": "ES2020", + "moduleResolution": "node", + "outDir": "build" + }, + "include": [ + "src/**/*" + ] +} + From c1507e6f43d40cfa5b71159df148f38e85feb70a Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 3 Nov 2021 17:25:46 +0100 Subject: [PATCH 013/180] webhooks: type user params --- webhooks/functions/.gitignore | 4 +- webhooks/functions/build/index.js | 503 -------------------------- webhooks/functions/build/index.js.map | 1 - webhooks/functions/src/index.ts | 32 +- 4 files changed, 29 insertions(+), 511 deletions(-) delete mode 100644 webhooks/functions/build/index.js delete mode 100644 webhooks/functions/build/index.js.map diff --git a/webhooks/functions/.gitignore b/webhooks/functions/.gitignore index 40b878db..e568fe8e 100644 --- a/webhooks/functions/.gitignore +++ b/webhooks/functions/.gitignore @@ -1 +1,3 @@ -node_modules/ \ No newline at end of file +node_modules/ + +build/ diff --git a/webhooks/functions/build/index.js b/webhooks/functions/build/index.js deleted file mode 100644 index 02a8073e..00000000 --- a/webhooks/functions/build/index.js +++ /dev/null @@ -1,503 +0,0 @@ -const { conversation, Media } = require("@assistant/conversation"); -const functions = require("firebase-functions"); -const admin = require("firebase-admin"); -admin.initializeApp(); -const db = admin.firestore(); -const { OpdsFetcher } = require("opds-fetcher-parser"); -const { ok } = require("assert"); -const app = conversation(); -const appHandle = app.handle.bind(app); -app.handle = (path, fn) => { - appHandle(path, async (conv) => { - let pass = false; - try { - const id = conv.user.params.bearerToken; - ok(id, "bearerToken not defined"); - const docRef = db.collection("user-storage").doc(id); - await Promise.resolve(fn(conv)); - pass = true; - await docRef.set(conv.user.params); - } - catch (e) { - console.error(e); - if (!pass) - await Promise.resolve(fn(conv)); - } - }); -}; -function isValidHttpUrl(string) { - let url; - try { - url = new URL(string); - } - catch (_) { - return false; - } - return url.protocol === "http:" || url.protocol === "https:"; -} -async function getPubsFromFeed(url) { - const opds = new OpdsFetcher(); - const feed = await opds.feedRequest(url); - ok(Array.isArray(feed.publications), "no publications"); - const list = feed.publications - .filter(({ openAccessLinks: l }) => { - return (Array.isArray(l) && - l[0] && - isValidHttpUrl(l[0].url)); - }) - .slice(0, 5) - .map(({ title, authors, openAccessLinks }) => ({ - title: title, - author: Array.isArray(authors) ? authors[0].name : "", - webpuburl: openAccessLinks[0].url, - })); - return list; -} -////////// -// TEST // -////////// -app.handle("test_player_sdk", (conv) => { - const nb = conv.intent.params.number.resolved; - switch (nb) { - case 123: - conv.user.params = { - ...conv.user.params, - p_i: 2, - p_n: "therese_raquin_emile_zola.json", - p_t: 123, - player: { - ...conv.user.params.player || {}, - ["therese_raquin_emile_zola.json"]: { - p_i: 2, - p_n: "therese_raquin_emile_zola.json", - p_t: 123, - }, - }, - }; - break; - case 456: - break; - case 789: - break; - } - console.log("test_PLAYER"); - console.log(conv.user.params); - conv.add(`test player ${nb}`); -}); -app.handle("setup_test_sdk", (conv) => { - const nb = conv.intent.params.number.resolved; - conv.user.params = { - bearerToken: `test-${nb}`, - }; - conv.add(`setup test ${nb}`); -}); -////////// -// TEST // -////////// -// ---------------- -// -// CONVERSATION START -// -// ---------------- -app.handle("cancel", (conv) => { - // Implement your code here - // conv.add("cancel"); -}); -app.handle("test_webhook", (conv) => { - conv.add("Webook works :", functions.config().debug.message || ""); - console.log("TEST OK"); -}); -// ----------- -// LVL2 MENU -// SELECTION -// ----------- -const WEBPUB_URL = "https://storage.googleapis.com/audiobook_edrlab/webpub/"; -const extract_name_from_url = (url) => { - const name = /\/(?:.(?!\/))+$/.exec(url)[0]; - if (typeof name === "string") - return name.slice(1); - return ""; -}; -// ----------- -// LVL3 MENU -// SELECTION -// ----------- -app.handle("selection_genre_lvl3", async (conv) => { - conv.add("sélection par genre"); -}); -app.handle("selection_thematic_list_lvl3", async (conv) => { - conv.add("sélection par liste thématique"); -}); -const SELECTION_URL = "https://storage.googleapis.com/audiobook_edrlab/groups/popular.json"; -app.handle("selection_my_list_lvl3", async (conv) => { - const url = SELECTION_URL; - const list = await getPubsFromFeed(url); - console.log("PUBs: ", list); - const length = list.length; - if (length > 1) { - conv.scene.next.name = "select_pub_after_selection"; - conv.add(`Il y a ${length} publications :\n`); - let text = ""; - list.map(({ title, author }, i) => { - text += `numero ${i + 1} : ${title} ${author ? `de ${author}` : ""}\n`; - }); - conv.add(text); - } - else if (length === 1) { - conv.scene.next.name = "ask_to_resume_listening_at_last_offset"; - conv.user.params.p_n = extract_name_from_url(list[0].webpuburl); - } - else { - conv.scene.next.name = "home_members"; - conv.add("aucun résultat trouvé"); - } - console.log("selection_my_list_lvl3 EXIT"); -}); -// --------- -// LVL3 MENU -// SELECTION -// --------- -app.handle("select_publication_number_after_selection", async (conv) => { - console.log("select_publication_number START"); - const number = conv.intent.params.number.resolved; - const url = SELECTION_URL; - const list = await getPubsFromFeed(url); - const pub = list[number - 1]; - if (pub) { - console.log("PUB: ", pub); - const url = extract_name_from_url(pub.webpuburl); - if (!conv.user.params.player) { - conv.user.params.player = {}; - } - const history = conv.user.params.player[url]; - if (!history) { - conv.user.params.p_i = 0; - conv.user.params.p_t = 0; - } - else { - conv.user.params.p_i = history.i; - conv.user.params.p_t = history.t; - } - conv.user.params.p_n = url; - // should be specified - conv.scene.next.name = "ask_to_resume_listening_at_last_offset"; - } - else { - console.log("NO PUBS found !!"); - conv.add(`Le numéro ${number} est inconnu. Veuillez choisir un autre numéro.`); - conv.scene.next.name = "select_pub_after_selection"; - } - console.log("select_publication_number END"); -}); -// ----------- -// LVL2 MENU -// SELECTION -// ----------- -app.handle("reprendre_mon_livre_lvl2", (conv) => { - // void - const name = conv.user.params.p_n; - if (!name) { - conv.scene.next.name = "home_members"; - conv.add("aucune lecture en cours"); - } -}); -app.handle("ecouter_livre_audio_lvl2", (conv) => { - // void - console.log("écouter_livre_audio_lvl2"); - // first entry point for search - // - // VOID - // - // search_livre_lvl2 is the main entry point -}); -// ---------- -// LVL2 MENU -// SEARCH -// ---------- -const SEARCH_URL = "https://europe-west1-audiobooks-a6348.cloudfunctions.net/indexer?url=https://storage.googleapis.com/audiobook_edrlab/navigation/all.json&query={query}"; -// if scene.slot.status == "FINAL" => call search_livre_lvl2 -app.handle("search_livre_lvl2", async (conv) => { - // void - console.log("search_livre_lvl2 START"); - let query = null; - try { - query = conv.intent.params.query.resolved; - } - catch (_) { - // ignore - } - ok(typeof query === "string", "aucune requete demandée"); - conv.session.params.query = query; - const url = SEARCH_URL.replace("{query}", encodeURIComponent(query)); - console.log("search URL: ", url); - const list = await getPubsFromFeed(url); - console.log("PUBs: "); - console.log(list); - const length = list.length; - if (length > 1) { - conv.scene.next.name = "select_pub_after_search"; - conv.add(`Il y a ${length} publications :\n`); - let text = ""; - list.map(({ title, author }, i) => { - text += `numero ${i + 1} : ${title} ${author ? `de ${author}` : ""}\n`; - }); - conv.add(text); - } - else if (length === 1) { - conv.scene.next.name = "ask_to_resume_listening_at_last_offset"; - conv.user.params.p_n = extract_name_from_url(list[0].webpuburl); - } - else { - conv.scene.next.name = "search"; - conv.add("aucun résultat trouvé"); - } - console.log("search_livre_lvl2 STOP"); - // slot available for research -}); -app.handle("select_publication_number_after_search", async (conv) => { - console.log("select_publication_number START"); - const number = conv.intent.params.number.resolved; - console.log("NUMBER: ", number); - const query = conv.session.params.query; - ok(typeof query === "string", "aucune requete demandée"); - const url = SEARCH_URL.replace("{query}", encodeURIComponent(query)); - console.log("select_publication_number_after_search URL: ", url); - const list = await getPubsFromFeed(url); - const pub = list[number - 1]; - if (pub) { - console.log("PUB: ", pub); - const name = extract_name_from_url(pub.webpuburl); - if (!conv.user.params.player) { - conv.user.params.player = {}; - } - const history = conv.user.params.player[name]; - if (!history) { - conv.user.params.p_i = 0; - conv.user.params.p_t = 0; - } - else { - conv.user.params.p_i = history.i; - conv.user.params.p_t = history.t; - } - conv.user.params.p_n = name; - // should be specified - conv.scene.next.name = "ask_to_resume_listening_at_last_offset"; - } - else { - console.log("NO PUBS found !!"); - conv.add(`Le numéro ${number} est inconnu. Veuillez choisir un autre numéro.`); - conv.scene.next.name = "select_pub_after_search"; - } - console.log("select_publication_number END"); -}); -// ---------- -// LVL2 MENU -// SEARCH -// ---------- -app.handle("ask_to_resume_listening_at_last_offset", async (conv) => { - const { p_n: name, p_i, p_t } = conv.user.params; - if (name && (p_i > 0 || p_t > 0)) { - console.log("ask to resume enabled , wait yes or no"); - // ask yes or no in the no-code scene - const history = conv.user.params.player[name]; - const date = history.d; - // TODO: use the date info - conv.add("Voulez-vous reprendre la lecture là où elle s'était arrêtée ?"); - } - else { - console.log("no need to ask to resume"); - conv.scene.next.name = "player"; - } -}); -app.handle("ask_to_resume_listening_at_last_offset__yes", async (conv) => { - // nothing - // not used - conv.scene.next.name = "player"; -}); -app.handle("ask_to_resume_listening_at_last_offset__no", async (conv) => { - const name = conv.user.params.p_n; - if (name) { - console.log("erase ", name, " resume listening NO"); - conv.user.params.p_i = 0; - conv.user.params.p_t = 0; - } - conv.scene.next.name = "player"; -}); -// ---------- -// PLAYER -// ---------- -app.handle("player", async (conv) => { - const name = conv.user.params.p_n; - const url = WEBPUB_URL + name; - console.log("Player URL:", url); - ok(url, "url not defined"); - ok(isValidHttpUrl(url), "url not valid " + url); - const opds = new OpdsFetcher(); - const webpub = await opds.webpubRequest(url); - ok(webpub, "webpub not defined"); - const startIndexRaw = conv.user.params.p_i; - const startIndex = typeof startIndexRaw === "number" && - startIndexRaw <= webpub.readingOrders.length ? startIndexRaw : 0; - const startTimeRaw = conv.user.params.p_t; - const startTime = typeof startTimeRaw === "number" && - startTimeRaw <= (webpub.readingOrders[startIndex].duration || Infinity) ? startTimeRaw : 0; - const mediaObjects = webpub.readingOrders - .map((v, i) => ({ - name: `${webpub.title || ""} - ${i + 1}`, - url: v.url, - image: { - large: { - alt: webpub.title, - url: webpub.cover || "", - }, - }, - })).slice(startIndex); - console.log("Media list"); - console.log(mediaObjects); - console.log("Start Index = ", startIndex, " Start Time = ", startTime, " Start Time"); - conv.add(new Media({ - mediaObjects: mediaObjects, - mediaType: "AUDIO", - optionalMediaControls: ["PAUSED", "STOPPED"], - startOffset: `${startTime}s`, - })); -}); -// ---------- -// PLAYER -// ---------- -// //////////////////////// -// Media PLAYET CONTEXT // -// //////////////////////// -function persistMediaPlayer(conv) { - if (conv.request.context) { - // Persist the media progress value - const progress = parseInt(conv.request.context.media.progress, 10); - const index = conv.request.context.media.index; - const name = conv.user.params.p_n; - conv.user.params.p_i = index; - conv.user.params.p_t = progress; - if (!conv.user.params.player) { - conv.user.params.player = {}; - } - conv.user.params.player[name] = { - i: index, - t: progress, - d: new Date().getTime(), - }; - console.log("player persistence :"); - console.log(conv.user.params.player); - } - else { - console.log("NO conv.request.context !!"); - } -} -app.handle("reprendre_la_lecture", (conv) => { - persistMediaPlayer(conv); - // // Acknowledge pause/stop - // conv.add(new Media({ - // mediaType: 'MEDIA_STATUS_ACK' - // })); - conv.scene.next.name = "player"; -}); -app.handle("remaining_time", async (conv) => { - persistMediaPlayer(conv); - const name = conv.user.params.p_n; - ok(name, "titre non défini"); - const url = WEBPUB_URL + name; - ok(isValidHttpUrl(url), "url not valid " + url); - const opds = new OpdsFetcher(); - const webpub = await opds.webpubRequest(url); - ok(webpub, "webpub not defined"); - const index = conv.user.params.player_startIndex || 0; - const time = conv.user.params.player_startTime || 0; - let minutes = 0; - if (Array.isArray(webpub.readingOrders)) { - let remainingTime = 0; - for (let i = index + 1; i < webpub.readingOrders.length; i += 1) { - remainingTime += webpub.readingOrders[i].duration || 0; - } - const pos = (v) => (v < 0 ? 0 : v); - remainingTime += pos((webpub.readingOrders[index].duration || 0) - time); - if (remainingTime >= 60) { - minutes = Math.floor(remainingTime / 60); - } - } - const hours = Math.floor(minutes / 60); - if (hours) { - minutes = minutes % 60; - conv.add(`il reste ${hours} heures et ${minutes} minutes`); - } - else { - conv.add(`il reste ${minutes} minutes`); - } - // // Acknowledge pause/stop - // conv.add(new Media({ - // mediaType: 'MEDIA_STATUS_ACK' - // })); - conv.scene.next.name = "player"; -}); -// //////////////////////// -// Media PLAYET CONTEXT // -// //////////////////////// -// Media status -app.handle("media_status", (conv) => { - console.log("MediaStatus START"); - const mediaStatus = conv.intent.params.MEDIA_STATUS.resolved; - console.log("MediaStatus : ", mediaStatus); - switch (mediaStatus) { - case "FINISHED": - persistMediaPlayer(conv); - conv.scene.next.name = "home_members"; - // void - break; - case "FAILED": - // void - break; - case "PAUSED": - case "STOPPED": - persistMediaPlayer(conv); - // Acknowledge pause/stop - conv.add(new Media({ - mediaType: "MEDIA_STATUS_ACK", - })); - break; - default: - conv.add("media status incorrect"); - } - console.log("MediaStatus END"); -}); -// catch(catcher: ExceptionHandler): ConversationV3App -// ExceptionHandler(conv: TConversation, error: Error): any -app.catch((conv, error) => { - conv.add("une erreur s'est produite"); - console.log("ERROR"); - console.log(error); -}); -// middleware(middleware: ConversationV3Middleware): ConversationV3App -// ConversationV3Middleware(conv: ConversationV3, framework: BuiltinFrameworkMetadata): void | ConversationV3 & TConversationPlugin | Promise | Promise -app.middleware(async (conv) => { - console.log(conv.user.params); - console.log("=========="); - console.log(conv); - console.log("----------"); - try { - const id = conv.user.params.bearerToken; - ok(id, "bearerToken not defined"); - const docRef = db.collection("user-storage").doc(id); - const doc = await docRef.get(); - if (!doc.exists) { - console.log("No such document!"); - } - else { - console.log("Document data:", doc.data()); - conv.user.params = doc.data(); - } - } - catch (e) { - console.error("Middleware critical error firebase firestore"); - console.error(e); - } - // void -}); -exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app); -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/webhooks/functions/build/index.js.map b/webhooks/functions/build/index.js.map deleted file mode 100644 index ae545398..00000000 --- a/webhooks/functions/build/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,EAAC,YAAY,EAAE,KAAK,EAAC,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;AACjE,MAAM,SAAS,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAChD,MAAM,KAAK,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAExC,KAAK,CAAC,aAAa,EAAE,CAAC;AAEtB,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;AAE7B,MAAM,EAAC,WAAW,EAAC,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;AACrD,MAAM,EAAC,EAAE,EAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE/B,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;AAE3B,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEvC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE;IAExB,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAE7B,IAAI,IAAI,GAAG,KAAK,CAAC;QACjB,IAAI;YAEF,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;YAExC,EAAE,CAAC,EAAE,EAAE,yBAAyB,CAAC,CAAC;YAElC,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACrD,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;YAChC,IAAI,GAAG,IAAI,CAAC;YACZ,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SAEpC;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACjB,IAAI,CAAC,IAAI;gBACP,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;SAEnC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,SAAS,cAAc,CAAC,MAAM;IAC5B,IAAI,GAAG,CAAC;IAER,IAAI;QACF,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;KACvB;IAAC,OAAO,CAAC,EAAE;QACV,OAAO,KAAK,CAAC;KACd;IAED,OAAO,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC;AAC/D,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,GAAG;IAEhC,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAEzC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,iBAAiB,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY;SACzB,MAAM,CAAC,CAAC,EAAC,eAAe,EAAE,CAAC,EAAC,EAA8B,EAAE;QAC3D,OAAO,CACL,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC,CAAC;YACJ,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CACvB,CAAC;IACJ,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,EAAC,KAAK,EAAE,OAAO,EAAE,eAAe,EAAC,EAAE,EAAE,CAAC,CAAC;QAC3C,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;QACrD,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG;KAClC,CAAC,CAAC,CAAC;IAER,OAAO,IAAI,CAAC;AACd,CAAC;AAED,UAAU;AACV,UAAU;AACV,UAAU;AAEV,GAAG,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,IAAI,EAAE,EAAE;IAErC,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;IAE9C,QAAQ,EAAE,EAAE;QAEV,KAAK,GAAG;YAEN,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG;gBACjB,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM;gBACnB,GAAG,EAAE,CAAC;gBACN,GAAG,EAAE,gCAAgC;gBACrC,GAAG,EAAE,GAAG;gBACR,MAAM,EAAE;oBACN,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE;oBAChC,CAAC,gCAAgC,CAAC,EAAE;wBAClC,GAAG,EAAE,CAAC;wBACN,GAAG,EAAE,gCAAgC;wBACrC,GAAG,EAAE,GAAG;qBACT;iBACF;aACF,CAAC;YAEF,MAAM;QAER,KAAK,GAAG;YAEN,MAAM;QACR,KAAK,GAAG;YAEN,MAAM;KACT;IAED,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC3B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE9B,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,IAAI,EAAE,EAAE;IAEpC,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;IAE9C,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG;QACjB,WAAW,EAAE,QAAQ,EAAE,EAAE;KAC1B,CAAA;IAED,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;AAE/B,CAAC,CAAC,CAAC;AAEH,UAAU;AACV,UAAU;AACV,UAAU;AAEV,mBAAmB;AACnB,EAAE;AACF,qBAAqB;AACrB,EAAE;AACF,mBAAmB;AAEnB,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;IAC5B,2BAA2B;IAC3B,sBAAsB;AACxB,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE;IAElC,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AACzB,CAAC,CAAC,CAAC;AAEH,cAAc;AACd,YAAY;AACZ,aAAa;AACb,cAAc;AAGd,MAAM,UAAU,GAAG,yDAAyD,CAAC;AAE7E,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE,EAAE;IAEpC,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAE5C,IAAI,OAAO,IAAI,KAAK,QAAQ;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEvB,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC;AAEF,cAAc;AACd,YAAY;AACZ,YAAY;AACZ,cAAc;AAEd,GAAG,CAAC,MAAM,CAAC,sBAAsB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAEhD,IAAI,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;AAClC,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,MAAM,CAAC,8BAA8B,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAExD,IAAI,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;AAC7C,CAAC,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG,qEAAqE,CAAA;AAC3F,GAAG,CAAC,MAAM,CAAC,wBAAwB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAElD,MAAM,GAAG,GAAG,aAAa,CAAC;IAC1B,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAE5B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC3B,IAAI,MAAM,GAAG,CAAC,EAAE;QACd,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;QACpD,IAAI,CAAC,GAAG,CAAC,UAAU,MAAM,mBAAmB,CAAC,CAAC;QAE9C,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,IAAI,CAAC,GAAG,CAAC,CAAC,EAAC,KAAK,EAAE,MAAM,EAAC,EAAE,CAAC,EAAE,EAAE;YAC9B,IAAI,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;QACzE,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;KAChB;SAAM,IAAI,MAAM,KAAK,CAAC,EAAE;QACvB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,wCAAwC,CAAC;QAEhE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;KACjE;SAAM;QACL,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAEtC,IAAI,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;KACnC;IAED,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;AAE7C,CAAC,CAAC,CAAC;AAEH,YAAY;AACZ,YAAY;AACZ,YAAY;AACZ,YAAY;AAEZ,GAAG,CAAC,MAAM,CAAC,2CAA2C,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IACrE,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAE/C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;IAElD,MAAM,GAAG,GAAG,aAAa,CAAC;IAC1B,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7B,IAAI,GAAG,EAAE;QACP,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAE1B,MAAM,GAAG,GAAG,qBAAqB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAEjD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;YAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;SAC9B;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,EAAE;YACZ,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;SAC1B;aAAM;YACL,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC;SAClC;QACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC;QAE3B,sBAAsB;QACtB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,wCAAwC,CAAC;KACjE;SAAM;QACL,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,aAAa,MAAM,iDAAiD,CAAC,CAAC;QAC/E,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;KACrD;IAED,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;AAC/C,CAAC,CAAC,CAAC;AAGH,cAAc;AACd,YAAY;AACZ,aAAa;AACb,cAAc;AAEd,GAAG,CAAC,MAAM,CAAC,0BAA0B,EAAE,CAAC,IAAI,EAAE,EAAE;IAE9C,OAAO;IAEP,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IAClC,IAAI,CAAC,IAAI,EAAE;QACT,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QACtC,IAAI,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;KACrC;AAEH,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,MAAM,CAAC,0BAA0B,EAAE,CAAC,IAAI,EAAE,EAAE;IAC9C,OAAO;IAEP,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAExC,+BAA+B;IAC/B,EAAE;IACF,OAAO;IACP,EAAE;IACF,4CAA4C;AAC9C,CAAC,CAAC,CAAC;AAGH,aAAa;AACb,YAAY;AACZ,SAAS;AACT,aAAa;AAEb,MAAM,UAAU,GAAG,wJAAwJ,CAAC;AAE5K,4DAA4D;AAC5D,GAAG,CAAC,MAAM,CAAC,mBAAmB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAC7C,OAAO;IAEP,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IAEvC,IAAI,KAAK,GAAG,IAAI,CAAC;IAEjB,IAAI;QACF,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;KAC3C;IAAC,OAAO,CAAC,EAAE;QACV,SAAS;KACV;IAED,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,EAAE,yBAAyB,CAAC,CAAC;IACzD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;IAElC,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,SAAS,EAAE,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IAEjC,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAElB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC3B,IAAI,MAAM,GAAG,CAAC,EAAE;QACd,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;QACjD,IAAI,CAAC,GAAG,CAAC,UAAU,MAAM,mBAAmB,CAAC,CAAC;QAE9C,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,IAAI,CAAC,GAAG,CAAC,CAAC,EAAC,KAAK,EAAE,MAAM,EAAC,EAAE,CAAC,EAAE,EAAE;YAC9B,IAAI,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;QACzE,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;KAChB;SAAM,IAAI,MAAM,KAAK,CAAC,EAAE;QACvB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,wCAAwC,CAAC;QAEhE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;KACjE;SAAM;QACL,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;QAEhC,IAAI,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;KACnC;IAED,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IAEtC,8BAA8B;AAChC,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,MAAM,CAAC,wCAAwC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAClE,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAE/C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;IAElD,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;IACxC,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,EAAE,yBAAyB,CAAC,CAAC;IAEzD,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,SAAS,EAAE,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,8CAA8C,EAAE,GAAG,CAAC,CAAC;IAEjE,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7B,IAAI,GAAG,EAAE;QACP,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAE1B,MAAM,IAAI,GAAG,qBAAqB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAElD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;YAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;SAC9B;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,EAAE;YACZ,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAE,CAAC,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;SAC1B;aAAM;YACL,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC;SAClC;QACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC;QAE5B,sBAAsB;QACtB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,wCAAwC,CAAC;KACjE;SAAM;QACL,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,aAAa,MAAM,iDAAiD,CAAC,CAAC;QAC/E,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;KAClD;IAED,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;AAC/C,CAAC,CAAC,CAAC;AAGH,aAAa;AACb,YAAY;AACZ,SAAS;AACT,aAAa;AAEb,GAAG,CAAC,MAAM,CAAC,wCAAwC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAElE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IACjD,IAAI,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,EAAE;QAChC,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;QACtD,qCAAqC;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC;QACvB,0BAA0B;QAE1B,IAAI,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;KAC3E;SAAM;QACL,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;KACjC;AAEH,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,MAAM,CAAC,6CAA6C,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAEvE,UAAU;IACV,WAAW;IACX,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;AAElC,CAAC,CAAC,CAAC;AAGH,GAAG,CAAC,MAAM,CAAC,4CAA4C,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAEtE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IAClC,IAAI,IAAI,EAAE;QACR,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,sBAAsB,CAAC,CAAC;QACpD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;KAC1B;IACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;AAElC,CAAC,CAAC,CAAC;AAGH,aAAa;AACb,SAAS;AACT,aAAa;AAEb,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAClC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IAElC,MAAM,GAAG,GAAG,UAAU,GAAG,IAAI,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;IAChC,EAAE,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;IAC3B,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,gBAAgB,GAAG,GAAG,CAAC,CAAC;IAEhD,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAC7C,EAAE,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAEjC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IAC3C,MAAM,UAAU,GACd,OAAO,aAAa,KAAK,QAAQ;QAC/B,aAAa,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IAErE,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IAC1C,MAAM,SAAS,GACb,OAAO,YAAY,KAAK,QAAQ;QAC9B,YAAY,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAE/F,MAAM,YAAY,GAAG,MAAM,CAAC,aAAa;SACpC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACd,IAAI,EAAE,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE;QACxC,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,KAAK,EAAE;YACL,KAAK,EAAE;gBACL,GAAG,EAAE,MAAM,CAAC,KAAK;gBACjB,GAAG,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;aACxB;SACF;KACF,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAE1B,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC1B,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC1B,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,UAAU,EAAE,gBAAgB,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;IAEtF,IAAI,CAAC,GAAG,CACJ,IAAI,KAAK,CAAC;QACR,YAAY,EAAE,YAAY;QAC1B,SAAS,EAAE,OAAO;QAClB,qBAAqB,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC;QAC5C,WAAW,EAAE,GAAG,SAAS,GAAG;KAC7B,CAAC,CACL,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,aAAa;AACb,SAAS;AACT,aAAa;AAGb,2BAA2B;AAC3B,0BAA0B;AAC1B,2BAA2B;AAE3B,SAAS,kBAAkB,CAAC,IAAI;IAC9B,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;QACxB,mCAAmC;QAEnC,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACnE,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;QAElC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,QAAQ,CAAC;QAEhC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;YAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;SAC9B;QAED,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG;YAC9B,CAAC,EAAE,KAAK;YACR,CAAC,EAAE,QAAQ;YACX,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE;SACxB,CAAC;QAEF,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;KACtC;SAAM;QAEL,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;KAC3C;AACH,CAAC;AAED,GAAG,CAAC,MAAM,CAAC,sBAAsB,EAAE,CAAC,IAAI,EAAE,EAAE;IAC1C,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAEzB,4BAA4B;IAC5B,uBAAuB;IACvB,kCAAkC;IAClC,OAAO;IAEP,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;AAClC,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,MAAM,CAAC,gBAAgB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAC1C,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAEzB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IAClC,EAAE,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;IAE7B,MAAM,GAAG,GAAG,UAAU,GAAG,IAAI,CAAC;IAC9B,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,gBAAgB,GAAG,GAAG,CAAC,CAAC;IAEhD,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAC7C,EAAE,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAEjC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,IAAI,CAAC,CAAC;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,IAAI,CAAC,CAAC;IAEpD,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE;QACvC,IAAI,aAAa,GAAG,CAAC,CAAC;QACtB,KAAK,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;YAC/D,aAAa,IAAI,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC;SACxD;QACD,MAAM,GAAG,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACnC,aAAa,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAEzE,IAAI,aAAa,IAAI,EAAE,EAAE;YACvB,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,EAAE,CAAC,CAAC;SAC1C;KACF;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACvC,IAAI,KAAK,EAAE;QACT,OAAO,GAAG,OAAO,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,GAAG,CAAC,YAAY,KAAK,cAAc,OAAO,UAAU,CAAC,CAAC;KAC5D;SAAM;QACL,IAAI,CAAC,GAAG,CAAC,YAAY,OAAO,UAAU,CAAC,CAAC;KACzC;IAED,4BAA4B;IAC5B,uBAAuB;IACvB,kCAAkC;IAClC,OAAO;IAEP,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;AAClC,CAAC,CAAC,CAAC;AAEH,2BAA2B;AAC3B,0BAA0B;AAC1B,2BAA2B;AAE3B,eAAe;AACf,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE;IAClC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACjC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;IAC3C,QAAQ,WAAW,EAAE;QACnB,KAAK,UAAU;YACb,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;YAEtC,OAAO;YACP,MAAM;QACR,KAAK,QAAQ;YAEX,OAAO;YACP,MAAM;QACR,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS;YACZ,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACzB,yBAAyB;YACzB,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC;gBACjB,SAAS,EAAE,kBAAkB;aAC9B,CAAC,CAAC,CAAC;YACJ,MAAM;QACR;YACE,IAAI,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;KACtC;IAED,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;AACjC,CAAC,CAAC,CAAC;AAGH,oFAAoF;AACpF,2DAA2D;AAC3D,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;IACxB,IAAI,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IAEtC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACrB,CAAC,CAAC,CAAC;AAEH,+HAA+H;AAC/H,mMAAmM;AACnM,GAAG,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IAE5B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC1B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClB,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAE1B,IAAI;QAEF,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;QACxC,EAAE,CAAC,EAAE,EAAE,yBAAyB,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACrD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE;YACf,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;SAClC;aAAM;YACL,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;YAC1C,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;SAC/B;KACF;IAAC,OAAO,CAAC,EAAE;QAEV,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAC9D,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAClB;IAED,OAAO;AACT,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC"} \ No newline at end of file diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index a9db5247..083d3eb0 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -4,12 +4,32 @@ import * as admin from "firebase-admin"; import {OpdsFetcher} from "opds-fetcher-parser"; import {ok} from "assert"; import { MediaType, OptionalMediaControl } from "@assistant/conversation/dist/api/schema"; +import { User } from "@assistant/conversation/dist/conversation/handler"; admin.initializeApp(); const db = admin.firestore(); -const app = conversation(); +interface IUser extends User { + params: { + bearerToken: string; + p_i?: number; + p_t?: number; + p_n?: string; + player?: { + [name: string]: { + i: number; + t: number; + d: number; + }; + }; + }; +} +interface IConvesationWithParams extends ConversationV3 { + user: IUser; +} + +const app = conversation(); const appHandle: typeof app.handle = app.handle.bind(app); @@ -96,9 +116,9 @@ app.handle("test_player_sdk", (conv) => { player: { ...conv.user.params.player || {}, ["therese_raquin_emile_zola.json"]: { - p_i: 2, - p_n: "therese_raquin_emile_zola.json", - p_t: 123, + i: 2, + d: 0, + t: 123, }, }, }; @@ -554,8 +574,8 @@ app.handle("remaining_time", async (conv) => { const webpub = await opds.webpubRequest(url); ok(webpub, "webpub not defined"); - const index = conv.user.params.player_startIndex || 0; - const time = conv.user.params.player_startTime || 0; + const index = conv.user.params.p_i || 0; + const time = conv.user.params.p_t || 0; let minutes = 0; if (Array.isArray(webpub.readingOrders)) { From 40dc16d8ad9ed9490e8a290f8200aab5b06ae3bf Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 9 Nov 2021 17:24:16 +0100 Subject: [PATCH 014/180] strict null checks (PR #7) --- webhooks/functions/src/index.ts | 50 +++++++++++++++++++++++++------- webhooks/functions/tsconfig.json | 3 +- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 083d3eb0..523714f6 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -90,7 +90,7 @@ async function getPubsFromFeed(url: string) { .map(({title, authors, openAccessLinks}) => ({ title: title, author: Array.isArray(authors) ? authors[0].name : "", - webpuburl: openAccessLinks[0].url, + webpuburl: Array.isArray(openAccessLinks) ? openAccessLinks[0].url : [], })); return list; @@ -102,7 +102,7 @@ async function getPubsFromFeed(url: string) { app.handle("test_player_sdk", (conv) => { - const nb = conv.intent.params.number.resolved; + const nb = conv.intent.params?.number.resolved; switch (nb) { @@ -141,7 +141,7 @@ app.handle("test_player_sdk", (conv) => { app.handle("setup_test_sdk", (conv) => { - const nb = conv.intent.params.number.resolved; + const nb = conv.intent.params?.number.resolved; conv.user.params = { bearerToken: `test-${nb}`, @@ -182,7 +182,8 @@ const WEBPUB_URL = "https://storage.googleapis.com/audiobook_edrlab/webpub/"; const extract_name_from_url = (url: string) => { - const name = /\/(?:.(?!\/))+$/.exec(url)[0]; + const reg = /\/(?:.(?!\/))+$/.exec(url); + const name = reg ? reg[0] : undefined; if (typeof name === "string") return name.slice(1); @@ -215,6 +216,7 @@ app.handle("selection_my_list_lvl3", async (conv) => { const length = list.length; if (length > 1) { + // @ts-ignore conv.scene.next.name = "select_pub_after_selection"; conv.add(`Il y a ${length} publications :\n`); @@ -225,10 +227,13 @@ app.handle("selection_my_list_lvl3", async (conv) => { conv.add(text); } else if (length === 1) { + // @ts-ignore conv.scene.next.name = "ask_to_resume_listening_at_last_offset"; + // @ts-ignore conv.user.params.p_n = extract_name_from_url(list[0].webpuburl); } else { + // @ts-ignore conv.scene.next.name = "home_members"; conv.add("aucun résultat trouvé"); @@ -246,7 +251,7 @@ app.handle("selection_my_list_lvl3", async (conv) => { app.handle("select_publication_number_after_selection", async (conv) => { console.log("select_publication_number START"); - const number = conv.intent.params.number.resolved; + const number = conv.intent.params?.number.resolved; const url = SELECTION_URL; const list = await getPubsFromFeed(url); @@ -254,6 +259,7 @@ app.handle("select_publication_number_after_selection", async (conv) => { if (pub) { console.log("PUB: ", pub); + // @ts-ignore const url = extract_name_from_url(pub.webpuburl); if (!conv.user.params.player) { @@ -271,10 +277,12 @@ app.handle("select_publication_number_after_selection", async (conv) => { conv.user.params.p_n = url; // should be specified + // @ts-ignore conv.scene.next.name = "ask_to_resume_listening_at_last_offset"; } else { console.log("NO PUBS found !!"); conv.add(`Le numéro ${number} est inconnu. Veuillez choisir un autre numéro.`); + // @ts-ignore conv.scene.next.name = "select_pub_after_selection"; } @@ -293,6 +301,7 @@ app.handle("reprendre_mon_livre_lvl2", (conv) => { const name = conv.user.params.p_n; if (!name) { + // @ts-ignore conv.scene.next.name = "home_members"; conv.add("aucune lecture en cours"); } @@ -328,12 +337,13 @@ app.handle("search_livre_lvl2", async (conv) => { let query = null; try { - query = conv.intent.params.query.resolved; + query = conv.intent.params?.query.resolved; } catch (_) { // ignore } ok(typeof query === "string", "aucune requete demandée"); + // @ts-ignore conv.session.params.query = query; const url = SEARCH_URL.replace("{query}", encodeURIComponent(query)); @@ -346,6 +356,7 @@ app.handle("search_livre_lvl2", async (conv) => { const length = list.length; if (length > 1) { + // @ts-ignore conv.scene.next.name = "select_pub_after_search"; conv.add(`Il y a ${length} publications :\n`); @@ -356,10 +367,13 @@ app.handle("search_livre_lvl2", async (conv) => { conv.add(text); } else if (length === 1) { + // @ts-ignore conv.scene.next.name = "ask_to_resume_listening_at_last_offset"; + // @ts-ignore conv.user.params.p_n = extract_name_from_url(list[0].webpuburl); } else { + // @ts-ignore conv.scene.next.name = "search"; conv.add("aucun résultat trouvé"); @@ -373,9 +387,10 @@ app.handle("search_livre_lvl2", async (conv) => { app.handle("select_publication_number_after_search", async (conv) => { console.log("select_publication_number START"); - const number = conv.intent.params.number.resolved; + const number = conv.intent.params?.number.resolved; console.log("NUMBER: ", number); + // @ts-ignore const query = conv.session.params.query; ok(typeof query === "string", "aucune requete demandée"); @@ -387,6 +402,7 @@ app.handle("select_publication_number_after_search", async (conv) => { if (pub) { console.log("PUB: ", pub); + // @ts-ignore const name = extract_name_from_url(pub.webpuburl); if (!conv.user.params.player) { @@ -404,10 +420,13 @@ app.handle("select_publication_number_after_search", async (conv) => { conv.user.params.p_n = name; // should be specified + // @ts-ignore conv.scene.next.name = "ask_to_resume_listening_at_last_offset"; } else { console.log("NO PUBS found !!"); conv.add(`Le numéro ${number} est inconnu. Veuillez choisir un autre numéro.`); + + // @ts-ignore conv.scene.next.name = "select_pub_after_search"; } @@ -423,9 +442,11 @@ app.handle("select_publication_number_after_search", async (conv) => { app.handle("ask_to_resume_listening_at_last_offset", async (conv) => { const { p_n: name, p_i, p_t } = conv.user.params; + // @ts-ignore if (name && (p_i > 0 || p_t > 0)) { console.log("ask to resume enabled , wait yes or no"); // ask yes or no in the no-code scene + // @ts-ignore const history = conv.user.params.player[name]; const date = history.d; // TODO: use the date info @@ -433,6 +454,7 @@ app.handle("ask_to_resume_listening_at_last_offset", async (conv) => { conv.add("Voulez-vous reprendre la lecture là où elle s'était arrêtée ?"); } else { console.log("no need to ask to resume"); + // @ts-ignore conv.scene.next.name = "player"; } @@ -442,6 +464,7 @@ app.handle("ask_to_resume_listening_at_last_offset__yes", async (conv) => { // nothing // not used + // @ts-ignore conv.scene.next.name = "player"; }); @@ -455,6 +478,7 @@ app.handle("ask_to_resume_listening_at_last_offset__no", async (conv) => { conv.user.params.p_i = 0; conv.user.params.p_t = 0; } + // @ts-ignore conv.scene.next.name = "player"; }); @@ -525,8 +549,10 @@ function persistMediaPlayer(conv: ConversationV3) { if (conv.request.context) { // Persist the media progress value - const progress = parseInt(conv.request.context.media.progress, 10); - const index = conv.request.context.media.index; + const prog = conv.request.context.media?.progress || "0"; + + const progress = parseInt(prog, 10); + const index = conv.request.context.media?.index; const name = conv.user.params.p_n; conv.user.params.p_i = index; @@ -558,6 +584,7 @@ app.handle("reprendre_la_lecture", (conv) => { // mediaType: 'MEDIA_STATUS_ACK' // })); + // @ts-ignore conv.scene.next.name = "player"; }); @@ -604,6 +631,7 @@ app.handle("remaining_time", async (conv) => { // mediaType: 'MEDIA_STATUS_ACK' // })); + // @ts-ignore conv.scene.next.name = "player"; }); @@ -614,11 +642,12 @@ app.handle("remaining_time", async (conv) => { // Media status app.handle("media_status", (conv) => { console.log("MediaStatus START"); - const mediaStatus = conv.intent.params.MEDIA_STATUS.resolved; + const mediaStatus = conv.intent.params?.MEDIA_STATUS.resolved; console.log("MediaStatus : ", mediaStatus); switch (mediaStatus) { case "FINISHED": persistMediaPlayer(conv); + // @ts-ignore conv.scene.next.name = "home_members"; // void @@ -671,6 +700,7 @@ app.middleware(async (conv) => { console.log("No such document!"); } else { console.log("Document data:", doc.data()); + // @ts-ignore conv.user.params = doc.data(); } } catch (e) { diff --git a/webhooks/functions/tsconfig.json b/webhooks/functions/tsconfig.json index dd0b3ae2..3c62b06c 100644 --- a/webhooks/functions/tsconfig.json +++ b/webhooks/functions/tsconfig.json @@ -8,7 +8,8 @@ "lib": ["ES2020"], "module": "ES2020", "moduleResolution": "node", - "outDir": "build" + "outDir": "build", + "strictNullChecks": true }, "include": [ "src/**/*" From 8c12fab5419c06bf498fb000c162805c1f9ba2cc Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 9 Nov 2021 18:49:20 +0100 Subject: [PATCH 015/180] eslint --- webhooks/functions/.eslintrc.js | 20 + webhooks/functions/package-lock.json | 886 ++++++++++++++++++++++++++- webhooks/functions/package.json | 10 +- webhooks/functions/src/index.ts | 323 +++++----- 4 files changed, 1051 insertions(+), 188 deletions(-) create mode 100644 webhooks/functions/.eslintrc.js diff --git a/webhooks/functions/.eslintrc.js b/webhooks/functions/.eslintrc.js new file mode 100644 index 00000000..3052fffd --- /dev/null +++ b/webhooks/functions/.eslintrc.js @@ -0,0 +1,20 @@ +module.exports = { + "env": { + }, + "extends": [ + "google" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 13, + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint" + ], + "rules": { + "max-len": 0, + "require-jsdoc": 0, + "camelcase": 0 + } +}; diff --git a/webhooks/functions/package-lock.json b/webhooks/functions/package-lock.json index b20f5e9b..fc1c1384 100644 --- a/webhooks/functions/package-lock.json +++ b/webhooks/functions/package-lock.json @@ -47,6 +47,31 @@ } } }, + "@eslint/eslintrc": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.4.tgz", + "integrity": "sha512-h8Vx6MdxwWI2WM8/zREHMoqdgLNXEL4QX3MWSVMdyNJGvXVOs+6lp+m2hc3FnuMHDc4poxFNI20vCk0OmI4G0Q==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.0.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + } + } + }, "@firebase/app-types": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.7.0.tgz", @@ -235,6 +260,49 @@ "yargs": "^16.1.1" } }, + "@humanwhocodes/config-array": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.6.0.tgz", + "integrity": "sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, "@panva/asn1.js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", @@ -380,6 +448,12 @@ "@types/express": "*" } }, + "@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, "@types/lodash": { "version": "4.14.176", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.176.tgz", @@ -426,6 +500,111 @@ "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.31.tgz", "integrity": "sha512-bVy7s0nvaR5D1mT1a8ZkByHWNOGb6Vn4yi5TWhEdmyKlAG+08SA7Md6+jH+tYmMLueAwNeWvHHpeKrr6S4c4BA==" }, + "@typescript-eslint/eslint-plugin": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.3.1.tgz", + "integrity": "sha512-cFImaoIr5Ojj358xI/SDhjog57OK2NqlpxwdcgyxDA3bJlZcJq5CPzUXtpD7CxI2Hm6ATU7w5fQnnkVnmwpHqw==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "5.3.1", + "@typescript-eslint/scope-manager": "5.3.1", + "debug": "^4.3.2", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.2.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/experimental-utils": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.3.1.tgz", + "integrity": "sha512-RgFn5asjZ5daUhbK5Sp0peq0SSMytqcrkNfU4pnDma2D8P3ElZ6JbYjY8IMSFfZAJ0f3x3tnO3vXHweYg0g59w==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.3.1", + "@typescript-eslint/types": "5.3.1", + "@typescript-eslint/typescript-estree": "5.3.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.3.1.tgz", + "integrity": "sha512-TD+ONlx5c+Qhk21x9gsJAMRohWAUMavSOmJgv3JGy9dgPhuBd5Wok0lmMClZDyJNLLZK1JRKiATzCKZNUmoyfw==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.3.1", + "@typescript-eslint/types": "5.3.1", + "@typescript-eslint/typescript-estree": "5.3.1", + "debug": "^4.3.2" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.3.1.tgz", + "integrity": "sha512-XksFVBgAq0Y9H40BDbuPOTUIp7dn4u8oOuhcgGq7EoDP50eqcafkMVGrypyVGvDYHzjhdUCUwuwVUK4JhkMAMg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.3.1", + "@typescript-eslint/visitor-keys": "5.3.1" + } + }, + "@typescript-eslint/types": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.3.1.tgz", + "integrity": "sha512-bG7HeBLolxKHtdHG54Uac750eXuQQPpdJfCYuw4ZI3bZ7+GgKClMWM8jExBtp7NSP4m8PmLRM8+lhzkYnSmSxQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.3.1.tgz", + "integrity": "sha512-PwFbh/PKDVo/Wct6N3w+E4rLZxUDgsoII/GrWM2A62ETOzJd4M6s0Mu7w4CWsZraTbaC5UQI+dLeyOIFF1PquQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.3.1", + "@typescript-eslint/visitor-keys": "5.3.1", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.3.1.tgz", + "integrity": "sha512-3cHUzUuVTuNHx0Gjjt5pEHa87+lzyqOiHXy/Gz+SJOCW1mpw9xQHIIEwnKn+Thph1mgWyZ90nboOcSuZr/jTTQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.3.1", + "eslint-visitor-keys": "^3.0.0" + } + }, "abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -443,6 +622,18 @@ "negotiator": "0.6.2" } }, + "acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true + }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -462,26 +653,42 @@ "uri-js": "^4.2.2" } }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "optional": true + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "optional": true, "requires": { "color-convert": "^2.0.1" } }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, "arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", @@ -615,6 +822,15 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -640,6 +856,12 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -653,6 +875,16 @@ "traverse": ">=0.3.0 <0.4" } }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -668,7 +900,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "optional": true, "requires": { "color-name": "~1.1.4" } @@ -676,8 +907,7 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "optional": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "combined-stream": { "version": "1.0.8", @@ -759,6 +989,17 @@ "vary": "^1" } }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, "crypto-random-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", @@ -787,6 +1028,12 @@ "ms": "2.1.2" } }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -810,6 +1057,24 @@ "streamsearch": "0.1.2" } }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -910,6 +1175,15 @@ "once": "^1.4.0" } }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, "ent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", @@ -932,6 +1206,196 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.2.0.tgz", + "integrity": "sha512-erw7XmM+CLxTOickrimJ1SiF55jiNlVSp2qqm0NuBWPtHYQCegD5ZMaW0c3i5ytPqL+SSLaCxdvQXFPLJn+ABw==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.0.4", + "@humanwhocodes/config-array": "^0.6.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^6.0.0", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.2.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "eslint-scope": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-6.0.0.tgz", + "integrity": "sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "eslint-config-google": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", + "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", + "dev": true + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", + "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "dev": true + }, + "espree": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.0.0.tgz", + "integrity": "sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ==", + "dev": true, + "requires": { + "acorn": "^8.5.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.0.0" + } + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -1014,16 +1478,44 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, "fast-text-encoding": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==" }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, "faye-websocket": { "version": "0.11.4", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", @@ -1048,6 +1540,15 @@ "tough-cookie": "^2.3.3 || ^3.0.1 || ^4.0.0" } }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, "file-js": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/file-js/-/file-js-0.3.0.tgz", @@ -1076,6 +1577,15 @@ "unit-compare": "^1.0.1" } }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, "finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -1155,6 +1665,33 @@ "lodash": "^4.17.5" } }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", + "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", + "dev": true + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -1199,8 +1736,7 @@ "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "optional": true + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" }, "gaxios": { "version": "4.3.2", @@ -1271,6 +1807,38 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, "google-auth-library": { "version": "7.10.1", "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.10.1.tgz", @@ -1346,6 +1914,12 @@ "har-schema": "^2.0.0" } }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, "hash-stream-validation": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.4.tgz", @@ -1414,6 +1988,12 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ignore": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz", + "integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==", + "dev": true + }, "image-size": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.0.tgz", @@ -1422,11 +2002,20 @@ "queue": "6.0.2" } }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "optional": true + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, "inflight": { "version": "1.0.6", @@ -1447,12 +2036,33 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "optional": true }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, "is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", @@ -1480,6 +2090,12 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -1493,6 +2109,15 @@ "@panva/asn1.js": "^1.0.0" } }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", @@ -1516,6 +2141,12 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -1606,6 +2237,16 @@ "safe-buffer": "^5.0.1" } }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, "limiter": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", @@ -1662,6 +2303,12 @@ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", @@ -1725,11 +2372,27 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, "mime": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", @@ -1785,6 +2448,12 @@ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz", "integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==" }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", @@ -1852,6 +2521,20 @@ "ts-fetch": "github:panaC/ts_fetch#7f585951111aa0e9cb7fe7f99bdd927a9261cd7b" } }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -1861,6 +2544,15 @@ "yocto-queue": "^0.1.0" } }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -1871,11 +2563,23 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -1886,11 +2590,29 @@ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, "proper-lockfile": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-1.2.0.tgz", @@ -1994,6 +2716,12 @@ "inherits": "~2.0.3" } }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, "r2-lcp-js": { "version": "1.0.33", "resolved": "https://registry.npmjs.org/r2-lcp-js/-/r2-lcp-js-1.0.33.tgz", @@ -2096,6 +2824,12 @@ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -2159,6 +2893,12 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "optional": true }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, "retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -2175,6 +2915,12 @@ "extend": "^3.0.2" } }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -2183,6 +2929,15 @@ "glob": "^7.1.3" } }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2267,12 +3022,33 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, "signal-exit": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", "optional": true }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, "slugify": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.1.tgz", @@ -2354,17 +3130,31 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "optional": true, "requires": { "ansi-regex": "^5.0.1" } }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, "stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=", "optional": true }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, "ta-json-x": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/ta-json-x/-/ta-json-x-2.5.3.tgz", @@ -2386,6 +3176,21 @@ "uuid": "^8.0.0" } }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", @@ -2436,6 +3241,23 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -2449,6 +3271,21 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -2473,6 +3310,12 @@ "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", "dev": true }, + "typescript-eslint": { + "version": "0.0.1-alpha.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-0.0.1-alpha.0.tgz", + "integrity": "sha512-1hNKM37dAWML/2ltRXupOq2uqcdRQyDFphl+341NTPXFLLLiDhErXx8VtaSLh3xP7SyHZdcCgpt9boYYVb3fQg==", + "dev": true + }, "unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", @@ -2580,6 +3423,12 @@ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "optional": true }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -2624,6 +3473,21 @@ "webidl-conversions": "^3.0.0" } }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index 951a296a..4e013c83 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -7,7 +7,8 @@ "start": "npm run shell", "deploy": "firebase deploy --only functions", "logs": "firebase functions:log", - "build": "tsc" + "build": "tsc", + "lint": "eslint src/**" }, "engines": { "node": "14" @@ -20,8 +21,13 @@ "opds-fetcher-parser": "github:panaC/opds_fetcher_parser#efec695f50b386071ccf935396f0a8ea4750c9ae" }, "devDependencies": { + "@typescript-eslint/eslint-plugin": "^5.3.1", + "@typescript-eslint/parser": "^5.3.1", + "eslint": "^8.2.0", + "eslint-config-google": "^0.14.0", "firebase-functions-test": "^0.2.0", - "typescript": "^4.4.4" + "typescript": "^4.4.4", + "typescript-eslint": "0.0.1-alpha.0" }, "private": true } diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 523714f6..97f02592 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -1,10 +1,10 @@ -import {conversation, ConversationV3, Media} from "@assistant/conversation"; -import * as functions from "firebase-functions"; -import * as admin from "firebase-admin"; -import {OpdsFetcher} from "opds-fetcher-parser"; -import {ok} from "assert"; -import { MediaType, OptionalMediaControl } from "@assistant/conversation/dist/api/schema"; -import { User } from "@assistant/conversation/dist/conversation/handler"; +import {conversation, ConversationV3, Media} from '@assistant/conversation'; +import * as functions from 'firebase-functions'; +import * as admin from 'firebase-admin'; +import {OpdsFetcher} from 'opds-fetcher-parser'; +import {ok} from 'assert'; +import {MediaType, OptionalMediaControl} from '@assistant/conversation/dist/api/schema'; +import {User} from '@assistant/conversation/dist/conversation/handler'; admin.initializeApp(); @@ -34,26 +34,22 @@ const app = conversation(); const appHandle: typeof app.handle = app.handle.bind(app); app.handle = (path, fn) => { - const ret = appHandle(path, async (conv) => { - let pass = false; try { - const id = conv.user.params.bearerToken; - ok(id, "bearerToken not defined"); + ok(id, 'bearerToken not defined'); - const docRef = db.collection("user-storage").doc(id); + const docRef = db.collection('user-storage').doc(id); await Promise.resolve(fn(conv)); pass = true; await docRef.set(conv.user.params); - } catch (e) { console.error(e); - if (!pass) + if (!pass) { await Promise.resolve(fn(conv)); - + } } }); @@ -69,15 +65,14 @@ function isValidHttpUrl(string: string) { return false; } - return url.protocol === "http:" || url.protocol === "https:"; + return url.protocol === 'http:' || url.protocol === 'https:'; } async function getPubsFromFeed(url: string) { - const opds = new OpdsFetcher(); const feed = await opds.feedRequest(url); - ok(Array.isArray(feed.publications), "no publications"); + ok(Array.isArray(feed.publications), 'no publications'); const list = feed.publications .filter(({openAccessLinks: l}) /* : l is IOpdsLinkView[]*/ => { return ( @@ -89,33 +84,31 @@ async function getPubsFromFeed(url: string) { .slice(0, 5) .map(({title, authors, openAccessLinks}) => ({ title: title, - author: Array.isArray(authors) ? authors[0].name : "", + author: Array.isArray(authors) ? authors[0].name : '', webpuburl: Array.isArray(openAccessLinks) ? openAccessLinks[0].url : [], })); return list; } -////////// +// //////// // TEST // -////////// - -app.handle("test_player_sdk", (conv) => { +// //////// +app.handle('test_player_sdk', (conv) => { const nb = conv.intent.params?.number.resolved; switch (nb) { - case 123: conv.user.params = { ...conv.user.params, p_i: 2, - p_n: "therese_raquin_emile_zola.json", + p_n: 'therese_raquin_emile_zola.json', p_t: 123, player: { ...conv.user.params.player || {}, - ["therese_raquin_emile_zola.json"]: { + ['therese_raquin_emile_zola.json']: { i: 2, d: 0, t: 123, @@ -133,27 +126,25 @@ app.handle("test_player_sdk", (conv) => { break; } - console.log("test_PLAYER"); + console.log('test_PLAYER'); console.log(conv.user.params); conv.add(`test player ${nb}`); }); -app.handle("setup_test_sdk", (conv) => { - +app.handle('setup_test_sdk', (conv) => { const nb = conv.intent.params?.number.resolved; conv.user.params = { bearerToken: `test-${nb}`, - } + }; conv.add(`setup test ${nb}`); - }); -////////// +// //////// // TEST // -////////// +// //////// // ---------------- // @@ -161,34 +152,33 @@ app.handle("setup_test_sdk", (conv) => { // // ---------------- -app.handle("cancel", (conv) => { +app.handle('cancel', (conv) => { // Implement your code here // conv.add("cancel"); }); -app.handle("test_webhook", (conv) => { - - conv.add("Webook works :", functions.config().debug.message || ""); - console.log("TEST OK"); +app.handle('test_webhook', (conv) => { + conv.add('Webook works :', functions.config().debug.message || ''); + console.log('TEST OK'); }); // ----------- // LVL2 MENU -// SELECTION +// SELECTION // ----------- -const WEBPUB_URL = "https://storage.googleapis.com/audiobook_edrlab/webpub/"; +const WEBPUB_URL = 'https://storage.googleapis.com/audiobook_edrlab/webpub/'; const extract_name_from_url = (url: string) => { - const reg = /\/(?:.(?!\/))+$/.exec(url); const name = reg ? reg[0] : undefined; - if (typeof name === "string") + if (typeof name === 'string') { return name.slice(1); + } - return ""; + return ''; }; // ----------- @@ -196,51 +186,47 @@ const extract_name_from_url = (url: string) => { // SELECTION // ----------- -app.handle("selection_genre_lvl3", async (conv) => { - - conv.add("sélection par genre"); +app.handle('selection_genre_lvl3', async (conv) => { + conv.add('sélection par genre'); }); -app.handle("selection_thematic_list_lvl3", async (conv) => { - - conv.add("sélection par liste thématique"); +app.handle('selection_thematic_list_lvl3', async (conv) => { + conv.add('sélection par liste thématique'); }); -const SELECTION_URL = "https://storage.googleapis.com/audiobook_edrlab/groups/popular.json" -app.handle("selection_my_list_lvl3", async (conv) => { - +const SELECTION_URL = 'https://storage.googleapis.com/audiobook_edrlab/groups/popular.json'; +app.handle('selection_my_list_lvl3', async (conv) => { const url = SELECTION_URL; const list = await getPubsFromFeed(url); - console.log("PUBs: ", list); + console.log('PUBs: ', list); const length = list.length; if (length > 1) { // @ts-ignore - conv.scene.next.name = "select_pub_after_selection"; + conv.scene.next.name = 'select_pub_after_selection'; conv.add(`Il y a ${length} publications :\n`); - let text = ""; + let text = ''; list.map(({title, author}, i) => { - text += `numero ${i + 1} : ${title} ${author ? `de ${author}` : ""}\n`; + text += `numero ${i + 1} : ${title} ${author ? `de ${author}` : ''}\n`; }); conv.add(text); } else if (length === 1) { // @ts-ignore - conv.scene.next.name = "ask_to_resume_listening_at_last_offset"; + conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; // @ts-ignore conv.user.params.p_n = extract_name_from_url(list[0].webpuburl); } else { // @ts-ignore - conv.scene.next.name = "home_members"; + conv.scene.next.name = 'home_members'; - conv.add("aucun résultat trouvé"); + conv.add('aucun résultat trouvé'); } - console.log("selection_my_list_lvl3 EXIT"); - + console.log('selection_my_list_lvl3 EXIT'); }); // --------- @@ -248,8 +234,8 @@ app.handle("selection_my_list_lvl3", async (conv) => { // SELECTION // --------- -app.handle("select_publication_number_after_selection", async (conv) => { - console.log("select_publication_number START"); +app.handle('select_publication_number_after_selection', async (conv) => { + console.log('select_publication_number START'); const number = conv.intent.params?.number.resolved; @@ -257,7 +243,7 @@ app.handle("select_publication_number_after_selection", async (conv) => { const list = await getPubsFromFeed(url); const pub = list[number - 1]; if (pub) { - console.log("PUB: ", pub); + console.log('PUB: ', pub); // @ts-ignore const url = extract_name_from_url(pub.webpuburl); @@ -278,40 +264,38 @@ app.handle("select_publication_number_after_selection", async (conv) => { // should be specified // @ts-ignore - conv.scene.next.name = "ask_to_resume_listening_at_last_offset"; + conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; } else { - console.log("NO PUBS found !!"); + console.log('NO PUBS found !!'); conv.add(`Le numéro ${number} est inconnu. Veuillez choisir un autre numéro.`); // @ts-ignore - conv.scene.next.name = "select_pub_after_selection"; + conv.scene.next.name = 'select_pub_after_selection'; } - console.log("select_publication_number END"); + console.log('select_publication_number END'); }); // ----------- // LVL2 MENU -// SELECTION +// SELECTION // ----------- -app.handle("reprendre_mon_livre_lvl2", (conv) => { - +app.handle('reprendre_mon_livre_lvl2', (conv) => { // void const name = conv.user.params.p_n; if (!name) { // @ts-ignore - conv.scene.next.name = "home_members"; - conv.add("aucune lecture en cours"); + conv.scene.next.name = 'home_members'; + conv.add('aucune lecture en cours'); } - }); -app.handle("ecouter_livre_audio_lvl2", (conv) => { +app.handle('ecouter_livre_audio_lvl2', (conv) => { // void - console.log("écouter_livre_audio_lvl2"); + console.log('écouter_livre_audio_lvl2'); // first entry point for search // @@ -326,13 +310,13 @@ app.handle("ecouter_livre_audio_lvl2", (conv) => { // SEARCH // ---------- -const SEARCH_URL = "https://europe-west1-audiobooks-a6348.cloudfunctions.net/indexer?url=https://storage.googleapis.com/audiobook_edrlab/navigation/all.json&query={query}"; +const SEARCH_URL = 'https://europe-west1-audiobooks-a6348.cloudfunctions.net/indexer?url=https://storage.googleapis.com/audiobook_edrlab/navigation/all.json&query={query}'; // if scene.slot.status == "FINAL" => call search_livre_lvl2 -app.handle("search_livre_lvl2", async (conv) => { +app.handle('search_livre_lvl2', async (conv) => { // void - console.log("search_livre_lvl2 START"); + console.log('search_livre_lvl2 START'); let query = null; @@ -342,65 +326,65 @@ app.handle("search_livre_lvl2", async (conv) => { // ignore } - ok(typeof query === "string", "aucune requete demandée"); + ok(typeof query === 'string', 'aucune requete demandée'); // @ts-ignore conv.session.params.query = query; - - const url = SEARCH_URL.replace("{query}", encodeURIComponent(query)); - console.log("search URL: ", url); + + const url = SEARCH_URL.replace('{query}', encodeURIComponent(query)); + console.log('search URL: ', url); const list = await getPubsFromFeed(url); - console.log("PUBs: "); + console.log('PUBs: '); console.log(list); const length = list.length; if (length > 1) { // @ts-ignore - conv.scene.next.name = "select_pub_after_search"; + conv.scene.next.name = 'select_pub_after_search'; conv.add(`Il y a ${length} publications :\n`); - let text = ""; + let text = ''; list.map(({title, author}, i) => { - text += `numero ${i + 1} : ${title} ${author ? `de ${author}` : ""}\n`; + text += `numero ${i + 1} : ${title} ${author ? `de ${author}` : ''}\n`; }); conv.add(text); } else if (length === 1) { // @ts-ignore - conv.scene.next.name = "ask_to_resume_listening_at_last_offset"; + conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; // @ts-ignore conv.user.params.p_n = extract_name_from_url(list[0].webpuburl); } else { // @ts-ignore - conv.scene.next.name = "search"; + conv.scene.next.name = 'search'; - conv.add("aucun résultat trouvé"); + conv.add('aucun résultat trouvé'); } - console.log("search_livre_lvl2 STOP"); + console.log('search_livre_lvl2 STOP'); // slot available for research }); -app.handle("select_publication_number_after_search", async (conv) => { - console.log("select_publication_number START"); +app.handle('select_publication_number_after_search', async (conv) => { + console.log('select_publication_number START'); const number = conv.intent.params?.number.resolved; - console.log("NUMBER: ", number); + console.log('NUMBER: ', number); // @ts-ignore const query = conv.session.params.query; - ok(typeof query === "string", "aucune requete demandée"); - - const url = SEARCH_URL.replace("{query}", encodeURIComponent(query)); - console.log("select_publication_number_after_search URL: ", url); + ok(typeof query === 'string', 'aucune requete demandée'); + + const url = SEARCH_URL.replace('{query}', encodeURIComponent(query)); + console.log('select_publication_number_after_search URL: ', url); const list = await getPubsFromFeed(url); const pub = list[number - 1]; if (pub) { - console.log("PUB: ", pub); + console.log('PUB: ', pub); // @ts-ignore const name = extract_name_from_url(pub.webpuburl); @@ -421,16 +405,16 @@ app.handle("select_publication_number_after_search", async (conv) => { // should be specified // @ts-ignore - conv.scene.next.name = "ask_to_resume_listening_at_last_offset"; + conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; } else { - console.log("NO PUBS found !!"); + console.log('NO PUBS found !!'); conv.add(`Le numéro ${number} est inconnu. Veuillez choisir un autre numéro.`); // @ts-ignore - conv.scene.next.name = "select_pub_after_search"; + conv.scene.next.name = 'select_pub_after_search'; } - console.log("select_publication_number END"); + console.log('select_publication_number END'); }); @@ -439,48 +423,41 @@ app.handle("select_publication_number_after_search", async (conv) => { // SEARCH // ---------- -app.handle("ask_to_resume_listening_at_last_offset", async (conv) => { - - const { p_n: name, p_i, p_t } = conv.user.params; - // @ts-ignore +app.handle('ask_to_resume_listening_at_last_offset', async (conv) => { + const {p_n: name, p_i, p_t} = conv.user.params; + // @ts-ignore if (name && (p_i > 0 || p_t > 0)) { - console.log("ask to resume enabled , wait yes or no"); + console.log('ask to resume enabled , wait yes or no'); // ask yes or no in the no-code scene - // @ts-ignore - const history = conv.user.params.player[name]; - const date = history.d; + // const history = conv.user.params.player[name]; + // const date = history.d; // TODO: use the date info - - conv.add("Voulez-vous reprendre la lecture là où elle s'était arrêtée ?"); + + conv.add('Voulez-vous reprendre la lecture là où elle s\'était arrêtée ?'); } else { - console.log("no need to ask to resume"); + console.log('no need to ask to resume'); // @ts-ignore - conv.scene.next.name = "player"; + conv.scene.next.name = 'player'; } - }); -app.handle("ask_to_resume_listening_at_last_offset__yes", async (conv) => { - +app.handle('ask_to_resume_listening_at_last_offset__yes', async (conv) => { // nothing // not used - // @ts-ignore - conv.scene.next.name = "player"; - + // @ts-ignore + conv.scene.next.name = 'player'; }); -app.handle("ask_to_resume_listening_at_last_offset__no", async (conv) => { - +app.handle('ask_to_resume_listening_at_last_offset__no', async (conv) => { const name = conv.user.params.p_n; if (name) { - console.log("erase ", name, " resume listening NO"); + console.log('erase ', name, ' resume listening NO'); conv.user.params.p_i = 0; conv.user.params.p_t = 0; } - // @ts-ignore - conv.scene.next.name = "player"; - + // @ts-ignore + conv.scene.next.name = 'player'; }); @@ -488,43 +465,43 @@ app.handle("ask_to_resume_listening_at_last_offset__no", async (conv) => { // PLAYER // ---------- -app.handle("player", async (conv) => { +app.handle('player', async (conv) => { const name = conv.user.params.p_n; const url = WEBPUB_URL + name; - console.log("Player URL:", url); - ok(url, "url not defined"); - ok(isValidHttpUrl(url), "url not valid " + url); + console.log('Player URL:', url); + ok(url, 'url not defined'); + ok(isValidHttpUrl(url), 'url not valid ' + url); const opds = new OpdsFetcher(); const webpub = await opds.webpubRequest(url); - ok(webpub, "webpub not defined"); + ok(webpub, 'webpub not defined'); const startIndexRaw = conv.user.params.p_i; const startIndex = - typeof startIndexRaw === "number" && + typeof startIndexRaw === 'number' && startIndexRaw <= webpub.readingOrders.length ? startIndexRaw : 0; const startTimeRaw = conv.user.params.p_t; const startTime = - typeof startTimeRaw === "number" && + typeof startTimeRaw === 'number' && startTimeRaw <= (webpub.readingOrders[startIndex].duration || Infinity) ? startTimeRaw : 0; const mediaObjects = webpub.readingOrders .map((v, i) => ({ - name: `${webpub.title || ""} - ${i + 1}`, + name: `${webpub.title || ''} - ${i + 1}`, url: v.url, image: { large: { alt: webpub.title, - url: webpub.cover || "", + url: webpub.cover || '', }, }, })).slice(startIndex); - console.log("Media list"); + console.log('Media list'); console.log(mediaObjects); - console.log("Start Index = ", startIndex, " Start Time = ", startTime, " Start Time"); + console.log('Start Index = ', startIndex, ' Start Time = ', startTime, ' Start Time'); conv.add( new Media({ @@ -549,7 +526,7 @@ function persistMediaPlayer(conv: ConversationV3) { if (conv.request.context) { // Persist the media progress value - const prog = conv.request.context.media?.progress || "0"; + const prog = conv.request.context.media?.progress || '0'; const progress = parseInt(prog, 10); const index = conv.request.context.media?.index; @@ -568,15 +545,14 @@ function persistMediaPlayer(conv: ConversationV3) { d: new Date().getTime(), }; - console.log("player persistence :"); + console.log('player persistence :'); console.log(conv.user.params.player); } else { - - console.log("NO conv.request.context !!"); + console.log('NO conv.request.context !!'); } } -app.handle("reprendre_la_lecture", (conv) => { +app.handle('reprendre_la_lecture', (conv) => { persistMediaPlayer(conv); // // Acknowledge pause/stop @@ -584,22 +560,22 @@ app.handle("reprendre_la_lecture", (conv) => { // mediaType: 'MEDIA_STATUS_ACK' // })); - // @ts-ignore - conv.scene.next.name = "player"; + // @ts-ignore + conv.scene.next.name = 'player'; }); -app.handle("remaining_time", async (conv) => { +app.handle('remaining_time', async (conv) => { persistMediaPlayer(conv); const name = conv.user.params.p_n; - ok(name, "titre non défini"); + ok(name, 'titre non défini'); const url = WEBPUB_URL + name; - ok(isValidHttpUrl(url), "url not valid " + url); + ok(isValidHttpUrl(url), 'url not valid ' + url); const opds = new OpdsFetcher(); const webpub = await opds.webpubRequest(url); - ok(webpub, "webpub not defined"); + ok(webpub, 'webpub not defined'); const index = conv.user.params.p_i || 0; const time = conv.user.params.p_t || 0; @@ -631,8 +607,8 @@ app.handle("remaining_time", async (conv) => { // mediaType: 'MEDIA_STATUS_ACK' // })); - // @ts-ignore - conv.scene.next.name = "player"; + // @ts-ignore + conv.scene.next.name = 'player'; }); // //////////////////////// @@ -640,24 +616,24 @@ app.handle("remaining_time", async (conv) => { // //////////////////////// // Media status -app.handle("media_status", (conv) => { - console.log("MediaStatus START"); +app.handle('media_status', (conv) => { + console.log('MediaStatus START'); const mediaStatus = conv.intent.params?.MEDIA_STATUS.resolved; - console.log("MediaStatus : ", mediaStatus); + console.log('MediaStatus : ', mediaStatus); switch (mediaStatus) { - case "FINISHED": + case 'FINISHED': persistMediaPlayer(conv); - // @ts-ignore - conv.scene.next.name = "home_members"; + // @ts-ignore + conv.scene.next.name = 'home_members'; // void break; - case "FAILED": + case 'FAILED': // void break; - case "PAUSED": - case "STOPPED": + case 'PAUSED': + case 'STOPPED': persistMediaPlayer(conv); // Acknowledge pause/stop conv.add(new Media({ @@ -665,47 +641,44 @@ app.handle("media_status", (conv) => { })); break; default: - conv.add("media status incorrect"); + conv.add('media status incorrect'); } - console.log("MediaStatus END"); + console.log('MediaStatus END'); }); // catch(catcher: ExceptionHandler): ConversationV3App // ExceptionHandler(conv: TConversation, error: Error): any app.catch((conv, error) => { - conv.add("une erreur s'est produite"); + conv.add('une erreur s\'est produite'); - console.log("ERROR"); + console.log('ERROR'); console.log(error); }); // middleware(middleware: ConversationV3Middleware): ConversationV3App // ConversationV3Middleware(conv: ConversationV3, framework: BuiltinFrameworkMetadata): void | ConversationV3 & TConversationPlugin | Promise | Promise app.middleware(async (conv) => { - console.log(conv.user.params); - console.log("=========="); + console.log('=========='); console.log(conv); - console.log("----------"); + console.log('----------'); try { - const id = conv.user.params.bearerToken; - ok(id, "bearerToken not defined"); - const docRef = db.collection("user-storage").doc(id); + ok(id, 'bearerToken not defined'); + const docRef = db.collection('user-storage').doc(id); const doc = await docRef.get(); if (!doc.exists) { - console.log("No such document!"); + console.log('No such document!'); } else { - console.log("Document data:", doc.data()); - // @ts-ignore + console.log('Document data:', doc.data()); + // @ts-ignore conv.user.params = doc.data(); } } catch (e) { - - console.error("Middleware critical error firebase firestore"); + console.error('Middleware critical error firebase firestore'); console.error(e); } From f1c0a58770078f6452a3e7057a76d2ff55e06bae Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 10 Nov 2021 15:26:12 +0100 Subject: [PATCH 016/180] improve user-storage (PR #6) --- .github/workflows/webhooks-test.yml | 32 ++ webhooks/functions/.eslintrc.js | 3 +- webhooks/functions/package-lock.json | 440 +++++++++++++++++- webhooks/functions/package.json | 15 +- webhooks/functions/src/database/firestore.ts | 17 + webhooks/functions/src/database/index.ts | 6 + webhooks/functions/src/index.ts | 301 ++++++------ webhooks/functions/src/model/storage.dto.ts | 136 ++++++ .../functions/src/model/storage.interface.ts | 24 + webhooks/functions/src/model/storage.test.ts | 106 +++++ webhooks/functions/tsconfig.json | 4 +- 11 files changed, 913 insertions(+), 171 deletions(-) create mode 100644 .github/workflows/webhooks-test.yml create mode 100644 webhooks/functions/src/database/firestore.ts create mode 100644 webhooks/functions/src/database/index.ts create mode 100644 webhooks/functions/src/model/storage.dto.ts create mode 100644 webhooks/functions/src/model/storage.interface.ts create mode 100644 webhooks/functions/src/model/storage.test.ts diff --git a/.github/workflows/webhooks-test.yml b/.github/workflows/webhooks-test.yml new file mode 100644 index 00000000..2f1dff2e --- /dev/null +++ b/.github/workflows/webhooks-test.yml @@ -0,0 +1,32 @@ + +name: webhooks unitary tests + +on: + push: + branches: [ develop, mainp ] + # paths: + pull_request: + branches: [ develop, main ] + +jobs: + sdk-test-prod: + name: "webhooks unitary tests" + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [14.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + defaults: + run: + working-directory: './webhooks/functions' + + steps: + + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node }} + + - run: npm ci + - run: npm test + - run: npm run lint diff --git a/webhooks/functions/.eslintrc.js b/webhooks/functions/.eslintrc.js index 3052fffd..1554c48a 100644 --- a/webhooks/functions/.eslintrc.js +++ b/webhooks/functions/.eslintrc.js @@ -15,6 +15,7 @@ module.exports = { "rules": { "max-len": 0, "require-jsdoc": 0, - "camelcase": 0 + "camelcase": 0, + "new-cap": 0, } }; diff --git a/webhooks/functions/package-lock.json b/webhooks/functions/package-lock.json index fc1c1384..82171665 100644 --- a/webhooks/functions/package-lock.json +++ b/webhooks/functions/package-lock.json @@ -47,6 +47,21 @@ } } }, + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, "@eslint/eslintrc": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.4.tgz", @@ -378,6 +393,30 @@ "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "optional": true }, + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, "@types/aws-lambda": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-0.0.33.tgz", @@ -471,6 +510,12 @@ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, + "@types/mocha": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.0.0.tgz", + "integrity": "sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==", + "dev": true + }, "@types/node": { "version": "16.11.6", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz", @@ -495,6 +540,11 @@ "@types/node": "*" } }, + "@types/validator": { + "version": "13.6.6", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.6.6.tgz", + "integrity": "sha512-+qogUELb4gMhrMjSh/seKmGVvN+uQLfyqJAqYRWqVHsvBsUO2xDBCL8CJ/ZSukbd8vXaoYbpIssAmfLEzzBHEw==" + }, "@types/xmldom": { "version": "0.1.31", "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.31.tgz", @@ -605,6 +655,12 @@ "eslint-visitor-keys": "^3.0.0" } }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, "abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -634,6 +690,12 @@ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -672,6 +734,22 @@ "color-convert": "^2.0.1" } }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -768,6 +846,12 @@ "chainsaw": "~0.1.0" } }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, "bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", @@ -831,6 +915,12 @@ "fill-range": "^7.0.1" } }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -862,6 +952,12 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -885,11 +981,41 @@ "supports-color": "^7.1.0" } }, + "chokidar": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "class-transformer": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.4.0.tgz", + "integrity": "sha512-ETWD/H2TbWbKEi7m9N4Km5+cw1hNcqJSxlSYhsLsNjQzWWiZIYA1zafxpK9PwVfaZ6AqR5rrjPVUBGESm5tQUA==" + }, + "class-validator": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.13.1.tgz", + "integrity": "sha512-zWIeYFhUitvAHBwNhDdCRK09hWx+P0HUwFE8US8/CxFpMVzkUK8RJl7yOIE+BVu2lxyPNgeOaFv78tLE47jBIg==", + "requires": { + "@types/validator": "^13.1.3", + "libphonenumber-js": "^1.9.7", + "validator": "^13.5.2" + } + }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "optional": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -989,6 +1115,12 @@ "vary": "^1" } }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1028,6 +1160,12 @@ "ms": "2.1.2" } }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -1057,6 +1195,12 @@ "streamsearch": "0.1.2" } }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -1158,8 +1302,7 @@ "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "optional": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "encodeurl": { "version": "1.0.2", @@ -1198,8 +1341,7 @@ "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "optional": true + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, "escape-html": { "version": "1.0.3", @@ -1615,6 +1757,16 @@ } } }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, "firebase-admin": { "version": "9.12.0", "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.12.0.tgz", @@ -1665,6 +1817,12 @@ "lodash": "^4.17.5" } }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, "flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -1722,6 +1880,13 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, "fstream": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", @@ -1777,8 +1942,7 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "optional": true + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-stream": { "version": "6.0.1", @@ -1890,6 +2054,12 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, "gtoken": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.3.1.tgz", @@ -1926,6 +2096,12 @@ "integrity": "sha512-Gjzu0Xn7IagXVkSu9cSFuK1fqzwtLwFhNhVL8IFJijRNMgUttFbBSIAzKuSIrsFMO1+g1RlsoN49zPIbwPDMGQ==", "optional": true }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, "http-errors": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", @@ -2036,6 +2212,15 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2045,8 +2230,7 @@ "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "optional": true + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "is-glob": { "version": "4.0.3", @@ -2069,6 +2253,12 @@ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "optional": true }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -2085,6 +2275,12 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -2247,6 +2443,11 @@ "type-check": "~0.4.0" } }, + "libphonenumber-js": { + "version": "1.9.42", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.9.42.tgz", + "integrity": "sha512-UBtU0ylpZPKPT8NLIyQJWj/DToMFxmo3Fm5m6qDc0LATvf0SY0qUhaurCEvukAB9Fo+Ia2Anjzqwoupaa64fXg==" + }, "limiter": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", @@ -2257,6 +2458,15 @@ "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=" }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -2314,6 +2524,16 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, "long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", @@ -2362,6 +2582,12 @@ "semver": "^6.0.0" } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -2433,6 +2659,81 @@ "minimist": "^1.2.5" } }, + "mocha": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz", + "integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.2", + "debug": "4.3.2", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.7", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.1.25", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.1.5", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "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" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "nanoid": { + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", + "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + } + } + }, "moment": { "version": "2.29.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", @@ -2477,6 +2778,12 @@ "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.15.0.tgz", "integrity": "sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw==" }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -2539,11 +2846,19 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "optional": true, "requires": { "yocto-queue": "^0.1.0" } }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -2558,6 +2873,12 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -2792,6 +3113,15 @@ "yazl": "^2.5.1" } }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -2819,6 +3149,15 @@ "util-deprecate": "^1.0.1" } }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, "reflect-metadata": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", @@ -2890,8 +3229,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "optional": true + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "resolve-from": { "version": "4.0.0", @@ -3001,6 +3339,15 @@ } } }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, "serve-static": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", @@ -3110,7 +3457,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "optional": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -3236,6 +3582,34 @@ } } }, + "ts-node": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", + "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } + } + }, "tslib": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", @@ -3429,6 +3803,11 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, + "validator": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", + "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -3488,11 +3867,16 @@ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, + "workerpool": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", + "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", + "dev": true + }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "optional": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -3535,8 +3919,7 @@ "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "optional": true + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" }, "yallist": { "version": "4.0.0", @@ -3547,7 +3930,6 @@ "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "optional": true, "requires": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -3561,8 +3943,19 @@ "yargs-parser": { "version": "20.2.9", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "optional": true + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + } }, "yauzl": { "version": "2.10.0", @@ -3581,11 +3974,16 @@ "buffer-crc32": "~0.2.3" } }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "optional": true + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" } } } diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index 4e013c83..f4aeec2f 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -8,7 +8,8 @@ "deploy": "firebase deploy --only functions", "logs": "firebase functions:log", "build": "tsc", - "lint": "eslint src/**" + "test": "mocha --recursive --require ts-node/register src/**/*.test.ts", + "lint": "eslint src/**/*.ts" }, "engines": { "node": "14" @@ -16,17 +17,23 @@ "main": "build/index.js", "dependencies": { "@assistant/conversation": "^3.0.0", + "class-transformer": "^0.4.0", + "class-validator": "^0.13.1", "firebase-admin": "^9.8.0", "firebase-functions": "^3.14.1", - "opds-fetcher-parser": "github:panaC/opds_fetcher_parser#efec695f50b386071ccf935396f0a8ea4750c9ae" + "opds-fetcher-parser": "github:panaC/opds_fetcher_parser#efec695f50b386071ccf935396f0a8ea4750c9ae", + "reflect-metadata": "^0.1.13" }, "devDependencies": { + "@types/mocha": "^9.0.0", + "firebase-functions-test": "^0.2.0", + "mocha": "^9.1.3", + "ts-node": "^10.4.0", + "typescript": "^4.4.4", "@typescript-eslint/eslint-plugin": "^5.3.1", "@typescript-eslint/parser": "^5.3.1", "eslint": "^8.2.0", "eslint-config-google": "^0.14.0", - "firebase-functions-test": "^0.2.0", - "typescript": "^4.4.4", "typescript-eslint": "0.0.1-alpha.0" }, "private": true diff --git a/webhooks/functions/src/database/firestore.ts b/webhooks/functions/src/database/firestore.ts new file mode 100644 index 00000000..dc40f446 --- /dev/null +++ b/webhooks/functions/src/database/firestore.ts @@ -0,0 +1,17 @@ +import * as admin from 'firebase-admin'; + +admin.initializeApp(); + +const db = admin.firestore(); + +export const push = async (key: string, value: FirebaseFirestore.DocumentData) => { + const docRef = db.collection('user-storage').doc(key); + await docRef.set(value); +}; + +export const pull = async (key: string) => { + const docRef = db.collection('user-storage').doc(key); + const doc = await docRef.get(); + + return doc; +}; diff --git a/webhooks/functions/src/database/index.ts b/webhooks/functions/src/database/index.ts new file mode 100644 index 00000000..cd1069f3 --- /dev/null +++ b/webhooks/functions/src/database/index.ts @@ -0,0 +1,6 @@ +import {push, pull} from './firestore'; + +export { + push, + pull, +}; diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 97f02592..fd499d33 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -1,29 +1,32 @@ -import {conversation, ConversationV3, Media} from '@assistant/conversation'; -import * as functions from 'firebase-functions'; -import * as admin from 'firebase-admin'; -import {OpdsFetcher} from 'opds-fetcher-parser'; -import {ok} from 'assert'; -import {MediaType, OptionalMediaControl} from '@assistant/conversation/dist/api/schema'; -import {User} from '@assistant/conversation/dist/conversation/handler'; - -admin.initializeApp(); +import {conversation, ConversationV3, Media } from "@assistant/conversation"; +import * as functions from "firebase-functions"; +import {OpdsFetcher} from "opds-fetcher-parser"; +import {ok} from "assert"; +import { User } from "@assistant/conversation/dist/conversation/handler"; + +// class-transformer +import 'reflect-metadata'; +import { pull, push } from "./database"; +import { IOpdsLinkView } from "opds-fetcher-parser/build/src/interface/opds"; +import { IStorage } from "./model/storage.interface"; +import { StorageDto } from "./model/storage.dto"; + +const BEARER_TOKEN_NOT_DEFINED = "bearer token not defined"; + +enum MediaType { + Audio = 'AUDIO', + MediaStatusACK = 'MEDIA_STATUS_ACK', + MediaTypeUnspecified = 'MEDIA_TYPE_UNSPECIFIED', +} -const db = admin.firestore(); +enum OptionalMediaControl { + OptionalMediaControlsUnspecified = 'OPTIONAL_MEDIA_CONTROLS_UNSPECIFIED', + Paused = 'PAUSED', + Stopped = 'STOPPED', +} interface IUser extends User { - params: { - bearerToken: string; - p_i?: number; - p_t?: number; - p_n?: string; - player?: { - [name: string]: { - i: number; - t: number; - d: number; - }; - }; - }; + params: StorageDto; } interface IConvesationWithParams extends ConversationV3 { user: IUser; @@ -35,31 +38,33 @@ const appHandle: typeof app.handle = app.handle.bind(app); app.handle = (path, fn) => { const ret = appHandle(path, async (conv) => { - let pass = false; - try { - const id = conv.user.params.bearerToken; - ok(id, 'bearerToken not defined'); + await Promise.resolve(fn(conv)); - const docRef = db.collection('user-storage').doc(id); - await Promise.resolve(fn(conv)); - pass = true; - await docRef.set(conv.user.params); + try { + + const bearerToken = conv.user.params.bearerToken; + ok(bearerToken, "bearerToken not defined"); + ok(bearerToken !== BEARER_TOKEN_NOT_DEFINED, "bearerToken not defined") + + const data = conv.user.params.extract(); + await push(bearerToken, data); } catch (e) { + + console.error("ERROR TO save user storage to the database"); console.error(e); - if (!pass) { - await Promise.resolve(fn(conv)); - } } + }); return ret; }; -function isValidHttpUrl(string: string) { - let url; +function isValidHttpUrl(string: string | undefined) { + let url: URL; try { + if (!string) throw "" url = new URL(string); } catch (_) { return false; @@ -77,15 +82,15 @@ async function getPubsFromFeed(url: string) { .filter(({openAccessLinks: l}) /* : l is IOpdsLinkView[]*/ => { return ( Array.isArray(l) && - l[0] && - isValidHttpUrl(l[0].url) + l[0] && + isValidHttpUrl(l[0].url) ); }) .slice(0, 5) .map(({title, authors, openAccessLinks}) => ({ title: title, - author: Array.isArray(authors) ? authors[0].name : '', - webpuburl: Array.isArray(openAccessLinks) ? openAccessLinks[0].url : [], + author: Array.isArray(authors) ? authors[0].name : "", + webpuburl: (openAccessLinks as IOpdsLinkView[])[0].url, })); return list; @@ -101,20 +106,15 @@ app.handle('test_player_sdk', (conv) => { switch (nb) { case 123: - conv.user.params = { - ...conv.user.params, - p_i: 2, - p_n: 'therese_raquin_emile_zola.json', - p_t: 123, - player: { - ...conv.user.params.player || {}, - ['therese_raquin_emile_zola.json']: { - i: 2, - d: 0, - t: 123, - }, - }, - }; + conv.user.params.player.current.index = 2; + conv.user.params.player.current.playing = true; + conv.user.params.player.current.time = 123; + conv.user.params.player.current.url = "https://storage.googleapis.com/audiobook_edrlab/webpub/therese_raquin_emile_zola.json"; + conv.user.params.player.history.set("https://storage.googleapis.com/audiobook_edrlab/webpub/therese_raquin_emile_zola.json", { + index: 2, + date: new Date(), + time: 123, + }); break; @@ -135,9 +135,7 @@ app.handle('test_player_sdk', (conv) => { app.handle('setup_test_sdk', (conv) => { const nb = conv.intent.params?.number.resolved; - conv.user.params = { - bearerToken: `test-${nb}`, - }; + conv.user.params.bearerToken = `test-${nb}`; conv.add(`setup test ${nb}`); }); @@ -170,16 +168,16 @@ app.handle('test_webhook', (conv) => { const WEBPUB_URL = 'https://storage.googleapis.com/audiobook_edrlab/webpub/'; -const extract_name_from_url = (url: string) => { - const reg = /\/(?:.(?!\/))+$/.exec(url); - const name = reg ? reg[0] : undefined; +// const extract_name_from_url = (url: string) => { - if (typeof name === 'string') { - return name.slice(1); - } +// const reg = /\/(?:.(?!\/))+$/.exec(url); +// const name = reg ? reg[0] : undefined; - return ''; -}; +// if (typeof name === "string") +// return name.slice(1); + +// return ""; +// }; // ----------- // LVL3 MENU @@ -217,11 +215,10 @@ app.handle('selection_my_list_lvl3', async (conv) => { // @ts-ignore conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; - // @ts-ignore - conv.user.params.p_n = extract_name_from_url(list[0].webpuburl); + conv.user.params.player.current.url = list[0].webpuburl; } else { // @ts-ignore - conv.scene.next.name = 'home_members'; + conv.scene.next.name = "home_members_lvl2"; conv.add('aucun résultat trouvé'); } @@ -245,22 +242,26 @@ app.handle('select_publication_number_after_selection', async (conv) => { if (pub) { console.log('PUB: ', pub); - // @ts-ignore - const url = extract_name_from_url(pub.webpuburl); + const url = pub.webpuburl; if (!conv.user.params.player) { - conv.user.params.player = {}; + conv.user.params.player = { + current: { + playing: false, + }, + history: new Map(), + }; } const history = conv.user.params.player[url]; if (!history) { - conv.user.params.p_i = 0; - conv.user.params.p_t = 0; + conv.user.params.player.current.index = 0; + conv.user.params.player.current.time = 0; } else { - conv.user.params.p_i = history.i; - conv.user.params.p_t = history.t; + conv.user.params.player.current.index = history.i; + conv.user.params.player.current.time = history.t; } - conv.user.params.p_n = url; + conv.user.params.player.current.url = url; // should be specified // @ts-ignore @@ -284,11 +285,11 @@ app.handle('select_publication_number_after_selection', async (conv) => { app.handle('reprendre_mon_livre_lvl2', (conv) => { // void - const name = conv.user.params.p_n; - if (!name) { + const url = conv.user.params.player.current.url; + if (!url) { // @ts-ignore - conv.scene.next.name = 'home_members'; - conv.add('aucune lecture en cours'); + conv.scene.next.name = "home_members_lvl2"; + conv.add("aucune lecture en cours"); } }); @@ -354,8 +355,7 @@ app.handle('search_livre_lvl2', async (conv) => { // @ts-ignore conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; - // @ts-ignore - conv.user.params.p_n = extract_name_from_url(list[0].webpuburl); + conv.user.params.player.current.url = list[0].webpuburl; } else { // @ts-ignore conv.scene.next.name = 'search'; @@ -386,22 +386,26 @@ app.handle('select_publication_number_after_search', async (conv) => { if (pub) { console.log('PUB: ', pub); - // @ts-ignore - const name = extract_name_from_url(pub.webpuburl); + const url = pub.webpuburl; if (!conv.user.params.player) { - conv.user.params.player = {}; + conv.user.params.player = { + current: { + playing: false, + }, + history: new Map(), + }; } - const history = conv.user.params.player[name]; + const history = conv.user.params.player[url]; if (!history) { - conv.user.params.p_i= 0; - conv.user.params.p_t = 0; + conv.user.params.player.current.index = 0; + conv.user.params.player.current.time = 0; } else { - conv.user.params.p_i = history.i; - conv.user.params.p_t = history.t; + conv.user.params.player.current.index = history.i; + conv.user.params.player.current.time = history.t; } - conv.user.params.p_n = name; + conv.user.params.player.current.url = url; // should be specified // @ts-ignore @@ -423,13 +427,15 @@ app.handle('select_publication_number_after_search', async (conv) => { // SEARCH // ---------- -app.handle('ask_to_resume_listening_at_last_offset', async (conv) => { - const {p_n: name, p_i, p_t} = conv.user.params; - // @ts-ignore - if (name && (p_i > 0 || p_t > 0)) { - console.log('ask to resume enabled , wait yes or no'); +app.handle("ask_to_resume_listening_at_last_offset", async (conv) => { + + console.log("start: ask_to_resume_last_offset"); + + const { url, index, time } = conv.user.params.player.current; + if (url && ((index && index > 0) || (time && time > 0))) { + console.log("ask to resume enabled , wait yes or no"); // ask yes or no in the no-code scene - // const history = conv.user.params.player[name]; + // const history = conv.user.params.player[url]; // const date = history.d; // TODO: use the date info @@ -449,12 +455,13 @@ app.handle('ask_to_resume_listening_at_last_offset__yes', async (conv) => { }); -app.handle('ask_to_resume_listening_at_last_offset__no', async (conv) => { - const name = conv.user.params.p_n; - if (name) { - console.log('erase ', name, ' resume listening NO'); - conv.user.params.p_i = 0; - conv.user.params.p_t = 0; +app.handle("ask_to_resume_listening_at_last_offset__no", async (conv) => { + + const url = conv.user.params.player.current.url; + if (url) { + console.log("erase ", url, " resume listening NO"); + conv.user.params.player.current.index = 0; + conv.user.params.player.current.time = 0; } // @ts-ignore conv.scene.next.name = 'player'; @@ -465,24 +472,23 @@ app.handle('ask_to_resume_listening_at_last_offset__no', async (conv) => { // PLAYER // ---------- -app.handle('player', async (conv) => { - const name = conv.user.params.p_n; +app.handle("player", async (conv) => { + const url = conv.user.params.player.current.url; - const url = WEBPUB_URL + name; - console.log('Player URL:', url); - ok(url, 'url not defined'); - ok(isValidHttpUrl(url), 'url not valid ' + url); + console.log("Player URL:", url); + ok(url, "url not defined"); + ok(isValidHttpUrl(url), "url not valid " + url); const opds = new OpdsFetcher(); const webpub = await opds.webpubRequest(url); ok(webpub, 'webpub not defined'); - const startIndexRaw = conv.user.params.p_i; + const startIndexRaw = conv.user.params.player.current.index; const startIndex = typeof startIndexRaw === 'number' && startIndexRaw <= webpub.readingOrders.length ? startIndexRaw : 0; - const startTimeRaw = conv.user.params.p_t; + const startTimeRaw = conv.user.params.player.current.time; const startTime = typeof startTimeRaw === 'number' && startTimeRaw <= (webpub.readingOrders[startIndex].duration || Infinity) ? startTimeRaw : 0; @@ -522,27 +528,33 @@ app.handle('player', async (conv) => { // Media PLAYET CONTEXT // // //////////////////////// -function persistMediaPlayer(conv: ConversationV3) { +function persistMediaPlayer(conv: IConvesationWithParams) { if (conv.request.context) { // Persist the media progress value - const prog = conv.request.context.media?.progress || '0'; - - const progress = parseInt(prog, 10); + const _progress = conv.request.context.media?.progress || "0"; + const progress = parseInt(_progress, 10); const index = conv.request.context.media?.index; - const name = conv.user.params.p_n; + const url = conv.user.params.player.current.url + + ok(url, "url not defined"); - conv.user.params.p_i = index; - conv.user.params.p_t = progress; + conv.user.params.player.current.index = index; + conv.user.params.player.current.time = progress; if (!conv.user.params.player) { - conv.user.params.player = {}; + conv.user.params.player = { + current: { + playing: false, + }, + history: new Map(), + }; } - conv.user.params.player[name] = { - i: index, - t: progress, - d: new Date().getTime(), + conv.user.params.player.history[url] = { + index: index, + time: progress, + date: new Date().getTime(), }; console.log('player persistence :'); @@ -567,18 +579,16 @@ app.handle('reprendre_la_lecture', (conv) => { app.handle('remaining_time', async (conv) => { persistMediaPlayer(conv); - const name = conv.user.params.p_n; - ok(name, 'titre non défini'); - - const url = WEBPUB_URL + name; - ok(isValidHttpUrl(url), 'url not valid ' + url); + const url = conv.user.params?.player?.current?.url; + ok(url, "url not defined") + ok(isValidHttpUrl(url), "url not valid " + url); const opds = new OpdsFetcher(); const webpub = await opds.webpubRequest(url); ok(webpub, 'webpub not defined'); - const index = conv.user.params.p_i || 0; - const time = conv.user.params.p_t || 0; + const index = conv.user.params.player.current.index|| 0; + const time = conv.user.params.player.current.time || 0; let minutes = 0; if (Array.isArray(webpub.readingOrders)) { @@ -624,7 +634,7 @@ app.handle('media_status', (conv) => { case 'FINISHED': persistMediaPlayer(conv); // @ts-ignore - conv.scene.next.name = 'home_members'; + conv.scene.next.name = "home_members_lvl2"; // void break; @@ -659,29 +669,34 @@ app.catch((conv, error) => { // middleware(middleware: ConversationV3Middleware): ConversationV3App // ConversationV3Middleware(conv: ConversationV3, framework: BuiltinFrameworkMetadata): void | ConversationV3 & TConversationPlugin | Promise | Promise -app.middleware(async (conv) => { +app.middleware(async (conv: IConvesationWithParams) => { + console.log(conv.user.params); console.log('=========='); console.log(conv); console.log('----------'); try { - const id = conv.user.params.bearerToken; - ok(id, 'bearerToken not defined'); - const docRef = db.collection('user-storage').doc(id); - const doc = await docRef.get(); - if (!doc.exists) { - console.log('No such document!'); - } else { - console.log('Document data:', doc.data()); - // @ts-ignore - conv.user.params = doc.data(); - } + + const bearerToken = typeof conv.user.params.bearerToken === "string" ? conv.user.params.bearerToken : ""; + ok(bearerToken, "bearerToken not defined"); + + const doc = await pull(bearerToken); + const data = doc.exists ? doc.data() : undefined; + const instance = StorageDto.create(data, bearerToken); + conv.user.params = instance; + } catch (e) { console.error('Middleware critical error firebase firestore'); console.error(e); + + conv.user.params = StorageDto.create(undefined, BEARER_TOKEN_NOT_DEFINED); } + console.log("user-params:"); + console.log(conv.user.params); + ok(conv.user.params instanceof StorageDto); + // void }); diff --git a/webhooks/functions/src/model/storage.dto.ts b/webhooks/functions/src/model/storage.dto.ts new file mode 100644 index 00000000..95ba8883 --- /dev/null +++ b/webhooks/functions/src/model/storage.dto.ts @@ -0,0 +1,136 @@ +import {IStorage, IStoragePlayer, IStoragePlayerCurrent, IStoragePlayerHistory} from './storage.interface'; +import {classToPlain, Exclude, plainToClass, Type} from 'class-transformer'; +import {Equals, IsBoolean, IsDate, IsNotEmpty, IsNumber, IsObject, IsOptional, IsPositive, IsString, IsUrl, ValidateNested, validateSync} from 'class-validator'; + +const DB_VERSION = 1; + +class StoragePlayerHistoryDto implements IStoragePlayerHistory { + @IsNumber() + index: number; + + @IsNumber() + time: number; + + @IsDate() + date: Date; + + // set(data: IStoragePlayerHistory) { + // this.date = data.date; + // this.index = data.index; + // this.time = data.time; + // } +} + +class StoragePlayerCurrentDto implements IStoragePlayerCurrent { + @IsPositive() + @IsNumber() + @IsOptional() + index?: number; + + @IsPositive() + @IsNumber() + @IsOptional() + time?: number; + + @IsUrl() + @IsString() + @IsOptional() + url?: string; + + @IsBoolean() + playing: boolean; + + // set(data: IStoragePlayerCurrent) { + // this.index = data.index; + // this.time = data.time; + // this.url = data.url; + // this.playing = data.playing; + // } + + constructor() { + this.playing = false; + } +} + +class StoragePlayerDto implements IStoragePlayer { + @IsObject() + @IsNotEmpty() + @Type(() => StoragePlayerCurrentDto) + @ValidateNested() + current: StoragePlayerCurrentDto; + + @IsNotEmpty() + @Type(() => StoragePlayerHistoryDto) + @ValidateNested() + history: Map; + + constructor() { + this.current = new StoragePlayerCurrentDto(); + this.history = new Map(); + } +} + +export class StorageDto implements IStorage { + @IsNumber() + @Equals(DB_VERSION) + dbVersion: number; + + @IsNotEmpty() + bearerToken: string; + + @IsObject() + @IsNotEmpty() + @Type(() => StoragePlayerDto) + @ValidateNested() + player: StoragePlayerDto; + + @Exclude() + snapshot: IStorage; + + constructor(bearerToken: string) { + this.dbVersion = DB_VERSION; + this.bearerToken = bearerToken; + this.player = new StoragePlayerDto(); + this.snapshot = classToPlain(this) as IStorage; + } + + @Exclude() + static create(data?: Record, bearerToken?: string): StorageDto { + if (!data && bearerToken) { + return new StorageDto(bearerToken); + } + + const storage = plainToClass(StorageDto, data); + const errors = validateSync(storage); + + if (errors.length) { + bearerToken = bearerToken || typeof data?.bearerToken === 'string' ? data?.bearerToken : undefined; + if (!bearerToken) { + throw new Error('bearerToken is empty'); + } + + console.error('Storage DTO \'create\' errors', errors); + console.error('new fresh storageDto created'); + + return new StorageDto(bearerToken); + } + + storage.snapshot = classToPlain(this) as IStorage; + return storage; + } + + @Exclude() + public extract(): Record { + const errors = validateSync(this); + + if (errors.length) { + console.error('storage DTO \'extract\' errors', errors); + console.error('return the last snapshot', this.snapshot); + + return this.snapshot; + } + + const storage = classToPlain(this); + return storage; + } +} diff --git a/webhooks/functions/src/model/storage.interface.ts b/webhooks/functions/src/model/storage.interface.ts new file mode 100644 index 00000000..561d489b --- /dev/null +++ b/webhooks/functions/src/model/storage.interface.ts @@ -0,0 +1,24 @@ + +export interface IStoragePlayerHistory { + index: number; + time: number; + date: Date; +} + +export interface IStoragePlayerCurrent { + index?: number; + time?: number; + url?: string; + playing: boolean; +} + +export interface IStoragePlayer { + current: IStoragePlayerCurrent; + history: Map; +} + +export interface IStorage { + bearerToken: string; + player: IStoragePlayer; +} + diff --git a/webhooks/functions/src/model/storage.test.ts b/webhooks/functions/src/model/storage.test.ts new file mode 100644 index 00000000..fe39ca3f --- /dev/null +++ b/webhooks/functions/src/model/storage.test.ts @@ -0,0 +1,106 @@ +import 'reflect-metadata'; +import {StorageDto} from './storage.dto'; +import * as assert from 'assert'; + + +describe('storage DTO', () => { + it('create storage object', () => { + const obj = { + dbVersion: 1, + bearerToken: undefined, + player: { + current: { + + playing: false, + }, + history: { + + }, + }, + }; + + assert.throws(() => StorageDto.create(obj)); + }); + + it('create storage object failed dbversion', () => { + const obj = { + dbVersion: 2, + bearerToken: 'test', + player: { + current: { + + playing: false, + }, + history: { + + }, + }, + }; + + const instance = StorageDto.create(obj); + + assert.ok(instance instanceof StorageDto); + assert.equal(instance.dbVersion, 1); + console.log(instance); + }); + + it('create storage object failed dbversion and bearer', () => { + const obj = { + dbVersion: 2, + bearerToken: undefined, + player: { + current: { + + playing: false, + }, + history: { + + }, + }, + }; + + assert.throws(() => StorageDto.create(obj)); + }); + + it('undefined storage', () => { + const instance = StorageDto.create(undefined, 'test'); + + const extr = instance.extract(); + + assert.deepEqual({ + dbVersion: 1, + bearerToken: 'test', + player: { + current: { + + playing: false, + }, + history: { + + }, + }, + }, extr); + }); + + it('bad validation extract', () => { + const instance = StorageDto.create(undefined, 'test'); + + instance.player.current.index = -34; + + const extr = instance.extract(); + + assert.deepEqual({ + dbVersion: 1, + bearerToken: 'test', + player: { + current: { + + playing: false, + }, + history: { + + }, + }, + }, extr); + }); +}); diff --git a/webhooks/functions/tsconfig.json b/webhooks/functions/tsconfig.json index 3c62b06c..7a7f7645 100644 --- a/webhooks/functions/tsconfig.json +++ b/webhooks/functions/tsconfig.json @@ -4,11 +4,11 @@ "noEmitOnError": true, "removeComments": false, "sourceMap": true, - "target": "ES2020", + "target": "ES5", "lib": ["ES2020"], - "module": "ES2020", "moduleResolution": "node", "outDir": "build", + "experimentalDecorators": true, "strictNullChecks": true }, "include": [ From 00482a64ce583713dad174b54c95b94ebb34c337 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 10 Nov 2021 15:27:53 +0100 Subject: [PATCH 017/180] typing sdk scene --- webhooks/functions/package.json | 3 ++- webhooks/functions/src/index.ts | 24 ++++++++---------------- webhooks/functions/src/sdk.d.ts | 1 + 3 files changed, 11 insertions(+), 17 deletions(-) create mode 100644 webhooks/functions/src/sdk.d.ts diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index f4aeec2f..86978320 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -9,7 +9,8 @@ "logs": "firebase functions:log", "build": "tsc", "test": "mocha --recursive --require ts-node/register src/**/*.test.ts", - "lint": "eslint src/**/*.ts" + "lint": "eslint src/**/*.ts", + "typed:scene": "echo \"export type TSdkScene = \" $(for I in `ls ../../sdk/test/custom/scenes | cut -d \".\" -f1`; do echo \"'$I' |\"; done) | sed 's/..$/;/' > src/sdk.d.ts" }, "engines": { "node": "14" diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index fd499d33..bcf3f921 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -2,7 +2,7 @@ import {conversation, ConversationV3, Media } from "@assistant/conversation"; import * as functions from "firebase-functions"; import {OpdsFetcher} from "opds-fetcher-parser"; import {ok} from "assert"; -import { User } from "@assistant/conversation/dist/conversation/handler"; +import { User, Scene } from "@assistant/conversation/dist/conversation/handler"; // class-transformer import 'reflect-metadata'; @@ -10,6 +10,7 @@ import { pull, push } from "./database"; import { IOpdsLinkView } from "opds-fetcher-parser/build/src/interface/opds"; import { IStorage } from "./model/storage.interface"; import { StorageDto } from "./model/storage.dto"; +import { TSdkScene } from "./sdk"; const BEARER_TOKEN_NOT_DEFINED = "bearer token not defined"; @@ -28,8 +29,14 @@ enum OptionalMediaControl { interface IUser extends User { params: StorageDto; } +interface IScene extends Scene { + next: { + name: TSdkScene; + } +} interface IConvesationWithParams extends ConversationV3 { user: IUser; + scene: IScene; } const app = conversation(); @@ -201,7 +208,6 @@ app.handle('selection_my_list_lvl3', async (conv) => { const length = list.length; if (length > 1) { - // @ts-ignore conv.scene.next.name = 'select_pub_after_selection'; conv.add(`Il y a ${length} publications :\n`); @@ -212,12 +218,10 @@ app.handle('selection_my_list_lvl3', async (conv) => { conv.add(text); } else if (length === 1) { - // @ts-ignore conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; conv.user.params.player.current.url = list[0].webpuburl; } else { - // @ts-ignore conv.scene.next.name = "home_members_lvl2"; conv.add('aucun résultat trouvé'); @@ -264,12 +268,10 @@ app.handle('select_publication_number_after_selection', async (conv) => { conv.user.params.player.current.url = url; // should be specified - // @ts-ignore conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; } else { console.log('NO PUBS found !!'); conv.add(`Le numéro ${number} est inconnu. Veuillez choisir un autre numéro.`); - // @ts-ignore conv.scene.next.name = 'select_pub_after_selection'; } @@ -287,7 +289,6 @@ app.handle('reprendre_mon_livre_lvl2', (conv) => { const url = conv.user.params.player.current.url; if (!url) { - // @ts-ignore conv.scene.next.name = "home_members_lvl2"; conv.add("aucune lecture en cours"); } @@ -341,7 +342,6 @@ app.handle('search_livre_lvl2', async (conv) => { const length = list.length; if (length > 1) { - // @ts-ignore conv.scene.next.name = 'select_pub_after_search'; conv.add(`Il y a ${length} publications :\n`); @@ -352,12 +352,10 @@ app.handle('search_livre_lvl2', async (conv) => { conv.add(text); } else if (length === 1) { - // @ts-ignore conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; conv.user.params.player.current.url = list[0].webpuburl; } else { - // @ts-ignore conv.scene.next.name = 'search'; conv.add('aucun résultat trouvé'); @@ -408,7 +406,6 @@ app.handle('select_publication_number_after_search', async (conv) => { conv.user.params.player.current.url = url; // should be specified - // @ts-ignore conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; } else { console.log('NO PUBS found !!'); @@ -442,7 +439,6 @@ app.handle("ask_to_resume_listening_at_last_offset", async (conv) => { conv.add('Voulez-vous reprendre la lecture là où elle s\'était arrêtée ?'); } else { console.log('no need to ask to resume'); - // @ts-ignore conv.scene.next.name = 'player'; } }); @@ -450,7 +446,6 @@ app.handle("ask_to_resume_listening_at_last_offset", async (conv) => { app.handle('ask_to_resume_listening_at_last_offset__yes', async (conv) => { // nothing // not used - // @ts-ignore conv.scene.next.name = 'player'; }); @@ -463,7 +458,6 @@ app.handle("ask_to_resume_listening_at_last_offset__no", async (conv) => { conv.user.params.player.current.index = 0; conv.user.params.player.current.time = 0; } - // @ts-ignore conv.scene.next.name = 'player'; }); @@ -572,7 +566,6 @@ app.handle('reprendre_la_lecture', (conv) => { // mediaType: 'MEDIA_STATUS_ACK' // })); - // @ts-ignore conv.scene.next.name = 'player'; }); @@ -633,7 +626,6 @@ app.handle('media_status', (conv) => { switch (mediaStatus) { case 'FINISHED': persistMediaPlayer(conv); - // @ts-ignore conv.scene.next.name = "home_members_lvl2"; // void diff --git a/webhooks/functions/src/sdk.d.ts b/webhooks/functions/src/sdk.d.ts new file mode 100644 index 00000000..88f20316 --- /dev/null +++ b/webhooks/functions/src/sdk.d.ts @@ -0,0 +1 @@ +export type TSdkScene = 'ask_to_resume_listening_at_last_offset' | 'home_lvl1' | 'home_lvl1_AccountLinking' | 'home_members_lvl2' | 'player' | 'search' | 'select_pub_after_search' | 'select_pub_after_selection' | 'selection_lvl3'; From a904c09fb8173d63da58f3afd160380f82b4eac7 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 10 Nov 2021 15:44:16 +0100 Subject: [PATCH 018/180] chore update firebase functions --- webhooks/functions/package-lock.json | 6 +++--- webhooks/functions/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/webhooks/functions/package-lock.json b/webhooks/functions/package-lock.json index 82171665..fd419bdc 100644 --- a/webhooks/functions/package-lock.json +++ b/webhooks/functions/package-lock.json @@ -1784,9 +1784,9 @@ } }, "firebase-functions": { - "version": "3.15.7", - "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.15.7.tgz", - "integrity": "sha512-ZD7r8eoWWebgs+mTqfH8NLUT2C0f7/cyAvIA1RSUdBVQZN7MBBt3oSlN/rL3e+m6tdlJz6YbQ3hrOKOGjOVYvQ==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.16.0.tgz", + "integrity": "sha512-6ISOn0JckMtpA3aJ/+wCCGhThUhBUrpZD+tSkUeolx0Vr+NoYFXA0+2YzJZa/A2MDU8gotPzUtnauLSEQvfClQ==", "requires": { "@types/cors": "^2.8.5", "@types/express": "4.17.3", diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index 86978320..840dc735 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -21,7 +21,7 @@ "class-transformer": "^0.4.0", "class-validator": "^0.13.1", "firebase-admin": "^9.8.0", - "firebase-functions": "^3.14.1", + "firebase-functions": "^3.16.0", "opds-fetcher-parser": "github:panaC/opds_fetcher_parser#efec695f50b386071ccf935396f0a8ea4750c9ae", "reflect-metadata": "^0.1.13" }, From 827742ba6cf85d0a48c75e8682a28c31b435bc5c Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 10 Nov 2021 15:49:52 +0100 Subject: [PATCH 019/180] fix deploy dev --- .github/workflows/functions-dev.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/functions-dev.yml b/.github/workflows/functions-dev.yml index 7a03ee79..123f1056 100644 --- a/.github/workflows/functions-dev.yml +++ b/.github/workflows/functions-dev.yml @@ -41,6 +41,18 @@ jobs: - name: Install Dependencies run: npm ci --no-audit working-directory: ${{ env.working-directory }} + + - name: test + run: npm test + working-directory: ${{ env.working-directory }} + + - name: lint + run: npm run lint + working-directory: ${{ env.working-directory }} + + - name: build + run: npm run build + working-directory: ${{ env.working-directory }} - name: set commit name to function config uses: w9jds/firebase-action@master From d0d21939389fde5bc95ee8c04352080ef670ee41 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 10 Nov 2021 17:17:55 +0100 Subject: [PATCH 020/180] clean --- webhooks/functions/src/index.ts | 116 +++++++++----------------- webhooks/functions/src/utils/index.ts | 39 +++++++++ 2 files changed, 79 insertions(+), 76 deletions(-) create mode 100644 webhooks/functions/src/utils/index.ts diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index bcf3f921..4a9ea02f 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -7,10 +7,9 @@ import { User, Scene } from "@assistant/conversation/dist/conversation/handler"; // class-transformer import 'reflect-metadata'; import { pull, push } from "./database"; -import { IOpdsLinkView } from "opds-fetcher-parser/build/src/interface/opds"; -import { IStorage } from "./model/storage.interface"; import { StorageDto } from "./model/storage.dto"; import { TSdkScene } from "./sdk"; +import { getPubsFromFeed, isValidHttpUrl } from "./utils"; const BEARER_TOKEN_NOT_DEFINED = "bearer token not defined"; @@ -34,12 +33,12 @@ interface IScene extends Scene { name: TSdkScene; } } -interface IConvesationWithParams extends ConversationV3 { +interface IConversationWithParams extends ConversationV3 { user: IUser; scene: IScene; } -const app = conversation(); +const app = conversation(); const appHandle: typeof app.handle = app.handle.bind(app); @@ -67,41 +66,48 @@ app.handle = (path, fn) => { return ret; }; -function isValidHttpUrl(string: string | undefined) { - let url: URL; +// catch(catcher: ExceptionHandler): ConversationV3App +// ExceptionHandler(conv: TConversation, error: Error): any +app.catch((conv, error) => { + conv.add('une erreur s\'est produite'); + + console.log('ERROR'); + console.log(error); +}); + +// middleware(middleware: ConversationV3Middleware): ConversationV3App +// ConversationV3Middleware(conv: ConversationV3, framework: BuiltinFrameworkMetadata): void | ConversationV3 & TConversationPlugin | Promise | Promise +app.middleware(async (conv: IConversationWithParams) => { + + console.log(conv.user.params); + console.log('=========='); + console.log(conv); + console.log('----------'); try { - if (!string) throw "" - url = new URL(string); - } catch (_) { - return false; + + const bearerToken = typeof conv.user.params.bearerToken === "string" ? conv.user.params.bearerToken : ""; + ok(bearerToken, "bearerToken not defined"); + + const doc = await pull(bearerToken); + const data = doc.exists ? doc.data() : undefined; + const instance = StorageDto.create(data, bearerToken); + conv.user.params = instance; + + } catch (e) { + console.error('Middleware critical error firebase firestore'); + console.error(e); + + conv.user.params = StorageDto.create(undefined, BEARER_TOKEN_NOT_DEFINED); } - return url.protocol === 'http:' || url.protocol === 'https:'; -} + console.log("user-params:"); + console.log(conv.user.params); + ok(conv.user.params instanceof StorageDto); -async function getPubsFromFeed(url: string) { - const opds = new OpdsFetcher(); - const feed = await opds.feedRequest(url); - - ok(Array.isArray(feed.publications), 'no publications'); - const list = feed.publications - .filter(({openAccessLinks: l}) /* : l is IOpdsLinkView[]*/ => { - return ( - Array.isArray(l) && - l[0] && - isValidHttpUrl(l[0].url) - ); - }) - .slice(0, 5) - .map(({title, authors, openAccessLinks}) => ({ - title: title, - author: Array.isArray(authors) ? authors[0].name : "", - webpuburl: (openAccessLinks as IOpdsLinkView[])[0].url, - })); + // void +}); - return list; -} // //////// // TEST // @@ -522,7 +528,7 @@ app.handle("player", async (conv) => { // Media PLAYET CONTEXT // // //////////////////////// -function persistMediaPlayer(conv: IConvesationWithParams) { +function persistMediaPlayer(conv: IConversationWithParams) { if (conv.request.context) { // Persist the media progress value @@ -610,7 +616,6 @@ app.handle('remaining_time', async (conv) => { // mediaType: 'MEDIA_STATUS_ACK' // })); - // @ts-ignore conv.scene.next.name = 'player'; }); @@ -650,46 +655,5 @@ app.handle('media_status', (conv) => { }); -// catch(catcher: ExceptionHandler): ConversationV3App -// ExceptionHandler(conv: TConversation, error: Error): any -app.catch((conv, error) => { - conv.add('une erreur s\'est produite'); - - console.log('ERROR'); - console.log(error); -}); - -// middleware(middleware: ConversationV3Middleware): ConversationV3App -// ConversationV3Middleware(conv: ConversationV3, framework: BuiltinFrameworkMetadata): void | ConversationV3 & TConversationPlugin | Promise | Promise -app.middleware(async (conv: IConvesationWithParams) => { - - console.log(conv.user.params); - console.log('=========='); - console.log(conv); - console.log('----------'); - - try { - - const bearerToken = typeof conv.user.params.bearerToken === "string" ? conv.user.params.bearerToken : ""; - ok(bearerToken, "bearerToken not defined"); - - const doc = await pull(bearerToken); - const data = doc.exists ? doc.data() : undefined; - const instance = StorageDto.create(data, bearerToken); - conv.user.params = instance; - - } catch (e) { - console.error('Middleware critical error firebase firestore'); - console.error(e); - - conv.user.params = StorageDto.create(undefined, BEARER_TOKEN_NOT_DEFINED); - } - - console.log("user-params:"); - console.log(conv.user.params); - ok(conv.user.params instanceof StorageDto); - - // void -}); exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app); diff --git a/webhooks/functions/src/utils/index.ts b/webhooks/functions/src/utils/index.ts new file mode 100644 index 00000000..593ad4b1 --- /dev/null +++ b/webhooks/functions/src/utils/index.ts @@ -0,0 +1,39 @@ +import { OpdsFetcher } from "opds-fetcher-parser"; +import * as assert from "assert"; +import { IOpdsLinkView } from "opds-fetcher-parser/build/src/interface/opds"; + +export function isValidHttpUrl(string: string | undefined) { + let url: URL; + + try { + if (!string) throw "" + url = new URL(string); + } catch (_) { + return false; + } + + return url.protocol === 'http:' || url.protocol === 'https:'; +} + +export async function getPubsFromFeed(url: string) { + const opds = new OpdsFetcher(); + const feed = await opds.feedRequest(url); + + assert.ok(Array.isArray(feed.publications), 'no publications'); + const list = feed.publications + .filter(({openAccessLinks: l}) /* : l is IOpdsLinkView[]*/ => { + return ( + Array.isArray(l) && + l[0] && + isValidHttpUrl(l[0].url) + ); + }) + .slice(0, 5) + .map(({title, authors, openAccessLinks}) => ({ + title: title, + author: Array.isArray(authors) ? authors[0].name : "", + webpuburl: (openAccessLinks as IOpdsLinkView[])[0].url, + })); + + return list; +} \ No newline at end of file From 90c17ebd1e69ac2ede3f6d6edce940933c73f46d Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 15 Nov 2021 16:36:35 +0100 Subject: [PATCH 021/180] finite state machine (PR #8) --- .github/workflows/sdk-test-dev.yml | 4 +- .../custom/global/actions.intent.MAIN.yaml | 9 +- .../custom/intents/resume_audiobook_lvl2.yaml | 4 - sdk/test/custom/intents/test_player_sdk.yaml | 6 + sdk/test/custom/intents/test_setup_sdk.yaml | 7 + ...sk_to_resume_listening_at_last_offset.yaml | 4 +- sdk/test/custom/scenes/home_lvl1.yaml | 37 +- sdk/test/custom/scenes/home_members_lvl2.yaml | 29 +- sdk/test/custom/scenes/player.yaml | 4 +- sdk/test/custom/scenes/search.yaml | 22 +- .../scenes/select_pub_after_search.yaml | 18 +- .../scenes/select_pub_after_selection.yaml | 18 +- sdk/test/custom/scenes/selection_lvl3.yaml | 8 +- .../webhooks/ActionsOnGoogleFulfillment.yaml | 44 +- webhooks/functions/package.json | 2 +- webhooks/functions/src/conversation/test.ts | 51 ++ webhooks/functions/src/index.ts | 527 ++++++------------ webhooks/functions/src/model/storage.dto.ts | 28 +- webhooks/functions/src/model/storage.test.ts | 92 +++ webhooks/functions/src/sdk.d.ts | 3 + .../functions/src/service/listPublication.ts | 26 + webhooks/functions/src/service/persist.ts | 27 + .../src/service/selectPublication.ts | 24 + webhooks/functions/src/type.ts | 35 ++ webhooks/functions/src/utils/index.ts | 20 +- 25 files changed, 571 insertions(+), 478 deletions(-) create mode 100644 sdk/test/custom/intents/test_player_sdk.yaml create mode 100644 sdk/test/custom/intents/test_setup_sdk.yaml create mode 100644 webhooks/functions/src/conversation/test.ts create mode 100644 webhooks/functions/src/service/listPublication.ts create mode 100644 webhooks/functions/src/service/persist.ts create mode 100644 webhooks/functions/src/service/selectPublication.ts create mode 100644 webhooks/functions/src/type.ts diff --git a/.github/workflows/sdk-test-dev.yml b/.github/workflows/sdk-test-dev.yml index 76e61227..bad835c5 100644 --- a/.github/workflows/sdk-test-dev.yml +++ b/.github/workflows/sdk-test-dev.yml @@ -5,8 +5,8 @@ on: push: branches: [ develop ] # paths: - pull_request: - branches: [ develop ] + # pull_request: + # branches: [ develop ] jobs: sdk-test-prod: diff --git a/sdk/test/custom/global/actions.intent.MAIN.yaml b/sdk/test/custom/global/actions.intent.MAIN.yaml index 849f748c..c43ab2e2 100644 --- a/sdk/test/custom/global/actions.intent.MAIN.yaml +++ b/sdk/test/custom/global/actions.intent.MAIN.yaml @@ -1,9 +1,2 @@ handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Bienvenue dans l'application d'écoute de livre audio valentin - hauy -transitionToScene: home_members_lvl2 + webhookHandler: main diff --git a/sdk/test/custom/intents/resume_audiobook_lvl2.yaml b/sdk/test/custom/intents/resume_audiobook_lvl2.yaml index aab5315b..838b6349 100644 --- a/sdk/test/custom/intents/resume_audiobook_lvl2.yaml +++ b/sdk/test/custom/intents/resume_audiobook_lvl2.yaml @@ -1,7 +1,3 @@ -parameters: -- name: number1 - type: - name: actions.type.Number trainingPhrases: - lecture d'($number1 'un' auto=true) livre - lecture de mon livre diff --git a/sdk/test/custom/intents/test_player_sdk.yaml b/sdk/test/custom/intents/test_player_sdk.yaml new file mode 100644 index 00000000..6cb23dcc --- /dev/null +++ b/sdk/test/custom/intents/test_player_sdk.yaml @@ -0,0 +1,6 @@ +parameters: +- name: number + type: + name: actions.type.Number +trainingPhrases: +- test player sdk ($number '123' auto=true) diff --git a/sdk/test/custom/intents/test_setup_sdk.yaml b/sdk/test/custom/intents/test_setup_sdk.yaml new file mode 100644 index 00000000..3efa6e61 --- /dev/null +++ b/sdk/test/custom/intents/test_setup_sdk.yaml @@ -0,0 +1,7 @@ +parameters: +- name: number + type: + name: actions.type.Number +trainingPhrases: +- test setup sdk ($number '123' auto=true) +- setup test sdk ($number '123' auto=true) diff --git a/sdk/test/custom/scenes/ask_to_resume_listening_at_last_offset.yaml b/sdk/test/custom/scenes/ask_to_resume_listening_at_last_offset.yaml index c575375b..f1a88cd8 100644 --- a/sdk/test/custom/scenes/ask_to_resume_listening_at_last_offset.yaml +++ b/sdk/test/custom/scenes/ask_to_resume_listening_at_last_offset.yaml @@ -1,11 +1,9 @@ intentEvents: - handler: - webhookHandler: ask_to_resume_listening_at_last_offset__yes + webhookHandler: ask_to_resume_listening_at_last_offset__intent__yes intent: "yes" - transitionToScene: player - handler: webhookHandler: ask_to_resume_listening_at_last_offset__no intent: "no" - transitionToScene: player onEnter: webhookHandler: ask_to_resume_listening_at_last_offset diff --git a/sdk/test/custom/scenes/home_lvl1.yaml b/sdk/test/custom/scenes/home_lvl1.yaml index 4bf88a05..e5800357 100644 --- a/sdk/test/custom/scenes/home_lvl1.yaml +++ b/sdk/test/custom/scenes/home_lvl1.yaml @@ -1,31 +1,18 @@ intentEvents: - handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Voici les informations sur l'association + webhookHandler: home_lvl1__intent__get_info_association_lvl1 intent: get_info_association_lvl1 - transitionToScene: home_lvl1 -- intent: enter_member_space_lvl1 - transitionToScene: home_lvl1_AccountLinking -- intent: resume_listening_player - transitionToScene: home_lvl1 -- intent: listen_audiobook_lvl1 - transitionToScene: home_lvl1_AccountLinking - handler: - webhookHandler: test_webhook + webhookHandler: home_lvl1__intent__enter_member_space_lvl1 + intent: enter_member_space_lvl1 +- handler: + webhookHandler: home_lvl1__intent__resume_listening_player + intent: resume_listening_player +- handler: + webhookHandler: home_lvl1__intent__listen_audiobook_lvl1 + intent: listen_audiobook_lvl1 +- handler: + webhookHandler: home_lvl1__intent__test_webhook intent: test_webhook - transitionToScene: home_lvl1 onEnter: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Que voulez-vous faire ? Vous pouvez dire informations ou espace - membres - suggestions: - - title: informations - - title: espace membres + webhookHandler: home_lvl1 diff --git a/sdk/test/custom/scenes/home_members_lvl2.yaml b/sdk/test/custom/scenes/home_members_lvl2.yaml index 2498e69c..ab947af9 100644 --- a/sdk/test/custom/scenes/home_members_lvl2.yaml +++ b/sdk/test/custom/scenes/home_members_lvl2.yaml @@ -1,25 +1,20 @@ intentEvents: - handler: - webhookHandler: ecouter_livre_audio_lvl2 + webhookHandler: home_members_lvl2__intent__listen_audiobook_lvl2 intent: listen_audiobook_lvl2 - transitionToScene: search - handler: - webhookHandler: reprendre_mon_livre_lvl2 + webhookHandler: home_members_lvl2__intent__resume_audiobook_lvl2 intent: resume_audiobook_lvl2 - transitionToScene: ask_to_resume_listening_at_last_offset - handler: - webhookHandler: selection_livre_lvl2 + webhookHandler: home_members__intent__selection_audiobook_lvl2 intent: selection_audiobook_lvl2 - transitionToScene: selection_lvl3 +- handler: + webhookHandler: test_setup_sdk + intent: test_setup_sdk + transitionToScene: home_members_lvl2 +- handler: + webhookHandler: test_player_sdk + intent: test_player_sdk + transitionToScene: home_members_lvl2 onEnter: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Bienvenue dans l'espace membres. Les commandes possibles sont, - sélection, lecture, recherche. Que voulez-vous faire ? - suggestions: - - title: selection d'un livre - - title: lecture du dernier livre - - title: recherche d'un livre + webhookHandler: home_members_lvl2 diff --git a/sdk/test/custom/scenes/player.yaml b/sdk/test/custom/scenes/player.yaml index 06957f78..9f4e8d93 100644 --- a/sdk/test/custom/scenes/player.yaml +++ b/sdk/test/custom/scenes/player.yaml @@ -1,9 +1,9 @@ intentEvents: - handler: - webhookHandler: reprendre_la_lecture + webhookHandler: player__intent__resume_listening_player intent: resume_listening_player - handler: - webhookHandler: remaining_time + webhookHandler: player__intent__remaining_time_player intent: remaing_time_player - handler: webhookHandler: media_status diff --git a/sdk/test/custom/scenes/search.yaml b/sdk/test/custom/scenes/search.yaml index 4d95c236..7a750ecb 100644 --- a/sdk/test/custom/scenes/search.yaml +++ b/sdk/test/custom/scenes/search.yaml @@ -1,21 +1,13 @@ -conditionalEvents: -- condition: scene.slots.status == "FINAL" - handler: - webhookHandler: search_livre_lvl2 intentEvents: -- intent: resume_listening_player - transitionToScene: search +- handler: + webhookHandler: search__intent__resume_listening_player + intent: resume_listening_player onEnter: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Que voulez-vous écouter ? Par exemple Zola + webhookHandler: search +onSlotUpdated: + webhookHandler: search__slot__query slots: -- commitBehavior: - writeSessionParam: query - name: query +- name: query required: true type: name: string diff --git a/sdk/test/custom/scenes/select_pub_after_search.yaml b/sdk/test/custom/scenes/select_pub_after_search.yaml index f6dc9f7b..4302dc5f 100644 --- a/sdk/test/custom/scenes/select_pub_after_search.yaml +++ b/sdk/test/custom/scenes/select_pub_after_search.yaml @@ -1,6 +1,7 @@ intentEvents: -- intent: resume_listening_player - transitionToScene: select_pub_after_search +- handler: + webhookHandler: select_pub_after_search__intent__resume_listening_player + intent: resume_listening_player - handler: staticPrompt: candidates: @@ -52,18 +53,11 @@ intentEvents: intent: actions.intent.NO_INPUT_FINAL transitionToScene: search onEnter: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Pour choisir une publication dite son numéro + webhookHandler: select_pub_after_search onSlotUpdated: - webhookHandler: select_publication_number_after_search + webhookHandler: select_pub_after_search__slot__number slots: -- commitBehavior: - writeSessionParam: number - name: number +- name: number required: true type: name: actions.type.Number diff --git a/sdk/test/custom/scenes/select_pub_after_selection.yaml b/sdk/test/custom/scenes/select_pub_after_selection.yaml index 10d12712..0c2c44cc 100644 --- a/sdk/test/custom/scenes/select_pub_after_selection.yaml +++ b/sdk/test/custom/scenes/select_pub_after_selection.yaml @@ -1,6 +1,7 @@ intentEvents: -- intent: resume_listening_player - transitionToScene: select_pub_after_selection +- handler: + webhookHandler: select_pub_after_selection__intent__resume_listening_player + intent: resume_listening_player - handler: staticPrompt: candidates: @@ -50,18 +51,11 @@ intentEvents: - speech: je n’ai pas compris le numéro intent: actions.intent.NO_INPUT_FINAL onEnter: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Pour choisir une publication dite son numéro + webhookHandler: select_pub_after_selection onSlotUpdated: - webhookHandler: select_publication_number_after_selection + webhookHandler: select_pub_after_selection__slot__number slots: -- commitBehavior: - writeSessionParam: number - name: number +- name: number required: true type: name: actions.type.Number diff --git a/sdk/test/custom/scenes/selection_lvl3.yaml b/sdk/test/custom/scenes/selection_lvl3.yaml index 583e652a..72d9a35a 100644 --- a/sdk/test/custom/scenes/selection_lvl3.yaml +++ b/sdk/test/custom/scenes/selection_lvl3.yaml @@ -1,10 +1,12 @@ intentEvents: - handler: - webhookHandler: selection_genre_lvl3 + webhookHandler: selection_lvl3__intent__selection_genre_lvl3 intent: selection_genre_lvl3 - handler: - webhookHandler: selection_thematic_list_lvl3 + webhookHandler: selection_lvl3__intent__selection_thematic_list_lvl3 intent: selection_thematic_list_lvl3 - handler: - webhookHandler: selection_my_list_lvl3 + webhookHandler: selection_lvl3__intent__selection_my_list_lvl3 intent: selection_my_list_lvl3 +onEnter: + webhookHandler: selection_lvl3 diff --git a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml index 814e3d4d..ed1a3b4d 100644 --- a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml @@ -1,22 +1,38 @@ handlers: - name: cancel -- name: ecouter_livre_audio_lvl2 -- name: reprendre_mon_livre_lvl2 - name: media_status - name: player -- name: reprendre_la_lecture -- name: remaining_time -- name: selection_livre_lvl2 -- name: select_publication_number_after_search -- name: select_publication_number_after_selection -- name: test_webhook -- name: search_livre_lvl2 - name: ask_to_resume_listening_at_last_offset -- name: ask_to_resume_listening_at_last_offset__yes - name: ask_to_resume_listening_at_last_offset__no -- name: selection_genre_lvl3 -- name: selection_thematic_list_lvl3 -- name: selection_my_list_lvl3 +- name: main +- name: home_lvl1 +- name: home_lvl1__intent__enter_member_space_lvl1 +- name: home_lvl1__intent__resume_listening_player +- name: home_lvl1__intent__get_info_association_lvl1 +- name: home_lvl1__intent__test_webhook +- name: home_lvl1__intent__listen_audiobook_lvl1 +- name: home_members_lvl2 +- name: home_members_lvl2__intent__listen_audiobook_lvl2 +- name: home_members_lvl2__intent__resume_audiobook_lvl2 +- name: home_members__intent__selection_audiobook_lvl2 +- name: selection_lvl3 +- name: selection_lvl3__intent__selection_thematic_list_lvl3 +- name: selection_lvl3__intent__selection_genre_lvl3 +- name: selection_lvl3__intent__selection_my_list_lvl3 +- name: select_pub_after_selection +- name: select_pub_after_selection__slot__number +- name: select_pub_after_selection__intent__resume_listening_player +- name: ask_to_resume_listening_at_last_offset__intent__yes +- name: player__intent__resume_listening_player +- name: player__intent__remaining_time_player +- name: search +- name: search__slot__query +- name: search__intent__resume_listening_player +- name: select_pub_after_search__slot__number +- name: select_pub_after_search__intent__resume_listening_player +- name: select_pub_after_search +- name: test_player_sdk +- name: test_setup_sdk httpsEndpoint: - baseUrl: https://us-central1-valentin-4.cloudfunctions.net/ActionsOnGoogleFulfillment + baseUrl: https://us-central1-valentin-5.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index 840dc735..9db66969 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -10,7 +10,7 @@ "build": "tsc", "test": "mocha --recursive --require ts-node/register src/**/*.test.ts", "lint": "eslint src/**/*.ts", - "typed:scene": "echo \"export type TSdkScene = \" $(for I in `ls ../../sdk/test/custom/scenes | cut -d \".\" -f1`; do echo \"'$I' |\"; done) | sed 's/..$/;/' > src/sdk.d.ts" + "typed:scene": "echo \"// npm run typed:scene \n\n\nexport type TSdkScene = \" $(for I in `ls ../../sdk/test/custom/scenes | cut -d \".\" -f1`; do echo \"'$I' |\"; done) | sed 's/..$/;/' > src/sdk.d.ts" }, "engines": { "node": "14" diff --git a/webhooks/functions/src/conversation/test.ts b/webhooks/functions/src/conversation/test.ts new file mode 100644 index 00000000..10ba35bf --- /dev/null +++ b/webhooks/functions/src/conversation/test.ts @@ -0,0 +1,51 @@ +import {TApp} from '..'; + +export const testConversation = (app: TApp) => { + app.handle('test_player_sdk', (conv) => { + const nb = conv.intent.params?.number.resolved; + + switch (nb) { + case 123: + + conv.user.params.player.current.index = 2; + conv.user.params.player.current.playing = true; + conv.user.params.player.current.time = 123; + conv.user.params.player.current.url = 'https://storage.googleapis.com/audiobook_edrlab/webpub/therese_raquin_emile_zola.json'; + conv.user.params.player.history.set('https://storage.googleapis.com/audiobook_edrlab/webpub/therese_raquin_emile_zola.json', { + index: 2, + date: new Date(), + time: 123, + }); + + break; + + case 456: + + break; + case 789: + + break; + } + + console.log('test_PLAYER'); + console.log(conv.user.params); + + conv.add(`test player ${nb}`); + }); + + app.handle('test_setup_sdk', (conv) => { + const nb = conv.intent.params?.number.resolved; + + + console.log('HELLLO '); + + + console.log(conv.user.params.bearerToken); + conv.user.params.bearerToken = `test-${nb}`; + console.log(conv.user.params.bearerToken); + + console.log('HELLLO '); + + conv.add(`setup test ${nb}`); + }); +}; diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 4a9ea02f..cca5e46c 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -1,44 +1,26 @@ -import {conversation, ConversationV3, Media } from "@assistant/conversation"; +import {conversation, Media } from "@assistant/conversation"; import * as functions from "firebase-functions"; import {OpdsFetcher} from "opds-fetcher-parser"; import {ok} from "assert"; -import { User, Scene } from "@assistant/conversation/dist/conversation/handler"; // class-transformer import 'reflect-metadata'; import { pull, push } from "./database"; import { StorageDto } from "./model/storage.dto"; -import { TSdkScene } from "./sdk"; -import { getPubsFromFeed, isValidHttpUrl } from "./utils"; +import { isValidHttpUrl } from "./utils"; +import { IConversationWithParams, MediaType, OptionalMediaControl } from "./type"; +import { persistMediaPlayer } from "./service/persist"; +import { listPublication } from "./service/listPublication"; +import { selectPublication } from "./service/selectPublication"; +import { testConversation } from "./conversation/test"; const BEARER_TOKEN_NOT_DEFINED = "bearer token not defined"; - -enum MediaType { - Audio = 'AUDIO', - MediaStatusACK = 'MEDIA_STATUS_ACK', - MediaTypeUnspecified = 'MEDIA_TYPE_UNSPECIFIED', -} - -enum OptionalMediaControl { - OptionalMediaControlsUnspecified = 'OPTIONAL_MEDIA_CONTROLS_UNSPECIFIED', - Paused = 'PAUSED', - Stopped = 'STOPPED', -} - -interface IUser extends User { - params: StorageDto; -} -interface IScene extends Scene { - next: { - name: TSdkScene; - } -} -interface IConversationWithParams extends ConversationV3 { - user: IUser; - scene: IScene; -} +const WEBPUB_URL = 'https://storage.googleapis.com/audiobook_edrlab/webpub/'; +const SELECTION_URL = 'https://storage.googleapis.com/audiobook_edrlab/groups/popular.json'; +const SEARCH_URL = 'https://europe-west1-audiobooks-a6348.cloudfunctions.net/indexer?url=https://storage.googleapis.com/audiobook_edrlab/navigation/all.json&query={query}'; const app = conversation(); +export type TApp = typeof app; const appHandle: typeof app.handle = app.handle.bind(app); @@ -61,11 +43,20 @@ app.handle = (path, fn) => { console.error(e); } + console.log("----------"); + console.log(conv.user.params); + console.log("----------"); + }); return ret; }; +// load test conversationnel +// not used in prod MODE +// @TODO Disable it in PROD-MODE +testConversation(app); + // catch(catcher: ExceptionHandler): ConversationV3App // ExceptionHandler(conv: TConversation, error: Error): any app.catch((conv, error) => { @@ -73,16 +64,19 @@ app.catch((conv, error) => { console.log('ERROR'); console.log(error); + + // conv.add(error.toString()); + + conv.scene.next.name = conv.scene.name; // loop }); // middleware(middleware: ConversationV3Middleware): ConversationV3App // ConversationV3Middleware(conv: ConversationV3, framework: BuiltinFrameworkMetadata): void | ConversationV3 & TConversationPlugin | Promise | Promise app.middleware(async (conv: IConversationWithParams) => { - console.log(conv.user.params); - console.log('=========='); - console.log(conv); - console.log('----------'); + if (!conv.session.params) { + conv.session.params = {}; + } try { @@ -101,233 +95,210 @@ app.middleware(async (conv: IConversationWithParams) => conv.user.params = StorageDto.create(undefined, BEARER_TOKEN_NOT_DEFINED); } - console.log("user-params:"); console.log(conv.user.params); + console.log('=========='); + console.log(conv.request); + console.log('----------'); + ok(conv.user.params instanceof StorageDto); // void }); +// ---------------- +// +// CONVERSATION START +// +// ---------------- -// //////// -// TEST // -// //////// - -app.handle('test_player_sdk', (conv) => { - const nb = conv.intent.params?.number.resolved; +app.handle('cancel', (conv) => { + // Implement your code here + // conv.add("cancel"); +}); - switch (nb) { - case 123: +app.handle('main', (conv) => { - conv.user.params.player.current.index = 2; - conv.user.params.player.current.playing = true; - conv.user.params.player.current.time = 123; - conv.user.params.player.current.url = "https://storage.googleapis.com/audiobook_edrlab/webpub/therese_raquin_emile_zola.json"; - conv.user.params.player.history.set("https://storage.googleapis.com/audiobook_edrlab/webpub/therese_raquin_emile_zola.json", { - index: 2, - date: new Date(), - time: 123, - }); + conv.add('Bienvenue dans l\'application d\'écoute de livre audio valentin hauy'); - break; + conv.scene.next.name = "home_members_lvl2"; +}); - case 456: +app.handle('home_lvl1', (conv) => { - break; - case 789: + conv.add('Que voulez-vous faire ? Vous pouvez dire informations ou espace membres'); - break; - } + // wait intent + // conv.scene.next.name +}); - console.log('test_PLAYER'); - console.log(conv.user.params); +app.handle('home_lvl1__intent__test_webhook', (conv) => { + conv.add('Webook works :', functions.config().debug.message || ''); + console.log('TEST OK'); - conv.add(`test player ${nb}`); + conv.scene.next.name = "home_lvl1"; }); -app.handle('setup_test_sdk', (conv) => { - const nb = conv.intent.params?.number.resolved; +app.handle('home_lvl1__intent__get_info_association_lvl1', (conv) => { - conv.user.params.bearerToken = `test-${nb}`; + conv.add('Voici les informations sur l\'association'); - conv.add(`setup test ${nb}`); + conv.scene.next.name = "home_lvl1"; }); -// //////// -// TEST // -// //////// +app.handle('home_lvl1__intent__enter_member_space_lvl1', (conv) => { -// ---------------- -// -// CONVERSATION START -// -// ---------------- + conv.scene.next.name = "home_lvl1_AccountLinking"; +}); -app.handle('cancel', (conv) => { - // Implement your code here - // conv.add("cancel"); +app.handle('home_lvl1__intent__resume_listening_player', (conv) => { + + conv.scene.next.name = "home_lvl1"; }); -app.handle('test_webhook', (conv) => { - conv.add('Webook works :', functions.config().debug.message || ''); - console.log('TEST OK'); +app.handle('home_lvl1__intent__listen_audiobook_lvl1', (conv) => { + + conv.scene.next.name = "home_lvl1_AccountLinking"; }); -// ----------- -// LVL2 MENU -// SELECTION -// ----------- +app.handle('home_members_lvl2', (conv) => { + conv.add("Bienvenue dans l'espace membres. Les commandes possibles sont: sélection, lecture, recherche. "); + conv.add("Que voulez-vous faire ?"); +}); -const WEBPUB_URL = 'https://storage.googleapis.com/audiobook_edrlab/webpub/'; +app.handle('home_members_lvl2__intent__listen_audiobook_lvl2', (conv) => { + // void -// const extract_name_from_url = (url: string) => { + console.log('listen_audiobook_lvl2'); -// const reg = /\/(?:.(?!\/))+$/.exec(url); -// const name = reg ? reg[0] : undefined; + // first entry point for search + // + // VOID + // + // search_livre_lvl2 is the main entry point -// if (typeof name === "string") -// return name.slice(1); + conv.scene.next.name = "search"; +}); -// return ""; -// }; +app.handle('home_members_lvl2__intent__resume_audiobook_lvl2', (conv) => { -// ----------- -// LVL3 MENU -// SELECTION -// ----------- + const url = conv.user.params.player.current.url; + if (!url) { + conv.scene.next.name = "home_members_lvl2"; + conv.add("aucune lecture en cours"); + } else + conv.scene.next.name = "ask_to_resume_listening_at_last_offset"; +}); + +app.handle('home_members__intent__selection_audiobook_lvl2', (conv) => { -app.handle('selection_genre_lvl3', async (conv) => { - conv.add('sélection par genre'); + conv.scene.next.name = "selection_lvl3"; }); -app.handle('selection_thematic_list_lvl3', async (conv) => { - conv.add('sélection par liste thématique'); +app.handle('selection_lvl3', (conv) => { + + conv.add("Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre, Que voulez-vous faire ?") + + // wait intent + // conv.scene.next.name }); -const SELECTION_URL = 'https://storage.googleapis.com/audiobook_edrlab/groups/popular.json'; -app.handle('selection_my_list_lvl3', async (conv) => { - const url = SELECTION_URL; - const list = await getPubsFromFeed(url); +app.handle('selection_lvl3__intent__selection_genre_lvl3', (conv) => { - console.log('PUBs: ', list); + conv.add("sélection par genre"); - const length = list.length; - if (length > 1) { - conv.scene.next.name = 'select_pub_after_selection'; - conv.add(`Il y a ${length} publications :\n`); + conv.scene.next.name = "home_members_lvl2"; +}); - let text = ''; - list.map(({title, author}, i) => { - text += `numero ${i + 1} : ${title} ${author ? `de ${author}` : ''}\n`; - }); +app.handle('selection_lvl3__intent__selection_thematic_list_lvl3', (conv) => { - conv.add(text); - } else if (length === 1) { - conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; + conv.add('sélection par liste thématique'); - conv.user.params.player.current.url = list[0].webpuburl; - } else { - conv.scene.next.name = "home_members_lvl2"; + conv.scene.next.name = "home_members_lvl2"; +}); - conv.add('aucun résultat trouvé'); - } +app.handle('selection_lvl3__intent__selection_my_list_lvl3', async (conv) => { + + const url = SELECTION_URL; + await listPublication(url, conv, 'select_pub_after_selection', 'home_members_lvl2'); console.log('selection_my_list_lvl3 EXIT'); }); -// --------- -// LVL3 MENU -// SELECTION -// --------- +app.handle('select_pub_after_selection', (conv) => { + + conv.add("Pour choisir une publication dite son numéro"); -app.handle('select_publication_number_after_selection', async (conv) => { + // wait slot number or intent +}); + +app.handle('select_pub_after_selection__slot__number', async (conv) => { console.log('select_publication_number START'); const number = conv.intent.params?.number.resolved; const url = SELECTION_URL; - const list = await getPubsFromFeed(url); - const pub = list[number - 1]; - if (pub) { - console.log('PUB: ', pub); + await selectPublication(url, number, conv); - const url = pub.webpuburl; - - if (!conv.user.params.player) { - conv.user.params.player = { - current: { - playing: false, - }, - history: new Map(), - }; - } - - const history = conv.user.params.player[url]; - if (!history) { - conv.user.params.player.current.index = 0; - conv.user.params.player.current.time = 0; - } else { - conv.user.params.player.current.index = history.i; - conv.user.params.player.current.time = history.t; - } - conv.user.params.player.current.url = url; + console.log('select_publication_number END'); +}); - // should be specified - conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; - } else { - console.log('NO PUBS found !!'); - conv.add(`Le numéro ${number} est inconnu. Veuillez choisir un autre numéro.`); - conv.scene.next.name = 'select_pub_after_selection'; - } +app.handle('select_pub_after_selection__intent__resume_listening_player', (conv) => { - console.log('select_publication_number END'); + conv.scene.next.name = "select_pub_after_selection"; }); +app.handle("ask_to_resume_listening_at_last_offset", async (conv) => { -// ----------- -// LVL2 MENU -// SELECTION -// ----------- + console.log("start: ask_to_resume_last_offset"); -app.handle('reprendre_mon_livre_lvl2', (conv) => { - // void + const { url, index, time } = conv.user.params.player.current; + if (isValidHttpUrl(url) && ((index && index > 0) || (time && time > 0))) { + console.log("ask to resume enabled , wait yes or no"); + // ask yes or no in the no-code scene + // const history = conv.user.params.player[url]; + // const date = history.d; + // TODO: use the date info - const url = conv.user.params.player.current.url; - if (!url) { - conv.scene.next.name = "home_members_lvl2"; - conv.add("aucune lecture en cours"); + conv.add('Voulez-vous reprendre la lecture là où elle s\'était arrêtée ?'); + + // wait intent + } else { + console.log('no need to ask to resume'); + conv.scene.next.name = 'player'; } }); -app.handle('ecouter_livre_audio_lvl2', (conv) => { - // void +app.handle('ask_to_resume_listening_at_last_offset__intent__yes', async (conv) => { - console.log('écouter_livre_audio_lvl2'); + conv.scene.next.name = 'player'; +}); - // first entry point for search - // - // VOID - // - // search_livre_lvl2 is the main entry point + +app.handle("ask_to_resume_listening_at_last_offset__intent__no", async (conv) => { + + const url = conv.user.params.player.current.url; + ok(isValidHttpUrl(url), "url not defined/valid " + url); + console.log("erase ", url, " resume listening NO"); + + conv.user.params.player.current.index = 0; + conv.user.params.player.current.time = 0; + conv.scene.next.name = 'player'; }); +app.handle('search', (conv) => { -// ---------- -// LVL2 MENU -// SEARCH -// ---------- + conv.add('Que voulez-vous écouter ? Par exemple Zola'); -const SEARCH_URL = 'https://europe-west1-audiobooks-a6348.cloudfunctions.net/indexer?url=https://storage.googleapis.com/audiobook_edrlab/navigation/all.json&query={query}'; + // wait query intent +}); -// if scene.slot.status == "FINAL" => call search_livre_lvl2 -app.handle('search_livre_lvl2', async (conv) => { +app.handle('search__slot__query', async (conv) => { // void console.log('search_livre_lvl2 START'); let query = null; - try { query = conv.intent.params?.query.resolved; } catch (_) { @@ -335,163 +306,70 @@ app.handle('search_livre_lvl2', async (conv) => { } ok(typeof query === 'string', 'aucune requete demandée'); - // @ts-ignore conv.session.params.query = query; const url = SEARCH_URL.replace('{query}', encodeURIComponent(query)); console.log('search URL: ', url); + await listPublication(url, conv, 'select_pub_after_search', 'search'); - const list = await getPubsFromFeed(url); + console.log('search_livre_lvl2 STOP'); - console.log('PUBs: '); - console.log(list); + // slot available for research +}); - const length = list.length; - if (length > 1) { - conv.scene.next.name = 'select_pub_after_search'; - conv.add(`Il y a ${length} publications :\n`); +app.handle('search__intent__resume_listening_player', (conv) => { - let text = ''; - list.map(({title, author}, i) => { - text += `numero ${i + 1} : ${title} ${author ? `de ${author}` : ''}\n`; - }); + conv.scene.next.name = "search"; +}); - conv.add(text); - } else if (length === 1) { - conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; +app.handle('select_pub_after_search', (conv) => { - conv.user.params.player.current.url = list[0].webpuburl; - } else { - conv.scene.next.name = 'search'; + conv.add("Pour choisir une publication dite son numéro"); - conv.add('aucun résultat trouvé'); - } + // wait intent +}); - console.log('search_livre_lvl2 STOP'); +app.handle('select_pub_after_search__intent__resume_listening_player', (conv) => { - // slot available for research + conv.scene.next.name = "select_pub_after_search"; }); -app.handle('select_publication_number_after_search', async (conv) => { +app.handle('select_pub_after_search__slot__number', async (conv) => { console.log('select_publication_number START'); const number = conv.intent.params?.number.resolved; console.log('NUMBER: ', number); - // @ts-ignore const query = conv.session.params.query; ok(typeof query === 'string', 'aucune requete demandée'); const url = SEARCH_URL.replace('{query}', encodeURIComponent(query)); - console.log('select_publication_number_after_search URL: ', url); - - const list = await getPubsFromFeed(url); - const pub = list[number - 1]; - if (pub) { - console.log('PUB: ', pub); - - const url = pub.webpuburl; - - if (!conv.user.params.player) { - conv.user.params.player = { - current: { - playing: false, - }, - history: new Map(), - }; - } - - const history = conv.user.params.player[url]; - if (!history) { - conv.user.params.player.current.index = 0; - conv.user.params.player.current.time = 0; - } else { - conv.user.params.player.current.index = history.i; - conv.user.params.player.current.time = history.t; - } - conv.user.params.player.current.url = url; - - // should be specified - conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; - } else { - console.log('NO PUBS found !!'); - conv.add(`Le numéro ${number} est inconnu. Veuillez choisir un autre numéro.`); - - // @ts-ignore - conv.scene.next.name = 'select_pub_after_search'; - } + console.log('select_pub_after_search__slot__number URL: ', url); + await selectPublication(url, number, conv); console.log('select_publication_number END'); }); - -// ---------- -// LVL2 MENU -// SEARCH -// ---------- - -app.handle("ask_to_resume_listening_at_last_offset", async (conv) => { - - console.log("start: ask_to_resume_last_offset"); - - const { url, index, time } = conv.user.params.player.current; - if (url && ((index && index > 0) || (time && time > 0))) { - console.log("ask to resume enabled , wait yes or no"); - // ask yes or no in the no-code scene - // const history = conv.user.params.player[url]; - // const date = history.d; - // TODO: use the date info - - conv.add('Voulez-vous reprendre la lecture là où elle s\'était arrêtée ?'); - } else { - console.log('no need to ask to resume'); - conv.scene.next.name = 'player'; - } -}); - -app.handle('ask_to_resume_listening_at_last_offset__yes', async (conv) => { - // nothing - // not used - conv.scene.next.name = 'player'; -}); - - -app.handle("ask_to_resume_listening_at_last_offset__no", async (conv) => { - - const url = conv.user.params.player.current.url; - if (url) { - console.log("erase ", url, " resume listening NO"); - conv.user.params.player.current.index = 0; - conv.user.params.player.current.time = 0; - } - conv.scene.next.name = 'player'; -}); - - -// ---------- -// PLAYER -// ---------- - app.handle("player", async (conv) => { - const url = conv.user.params.player.current.url; - console.log("Player URL:", url); - ok(url, "url not defined"); + const url = conv.user.params.player.current.url; ok(isValidHttpUrl(url), "url not valid " + url); + console.log("Player URL:", url); + + const startIndexRaw = conv.user.params.player.current.index; + const startTimeRaw = conv.user.params.player.current.time; const opds = new OpdsFetcher(); const webpub = await opds.webpubRequest(url); ok(webpub, 'webpub not defined'); - const startIndexRaw = conv.user.params.player.current.index; - const startIndex = - typeof startIndexRaw === 'number' && - startIndexRaw <= webpub.readingOrders.length ? startIndexRaw : 0; + const startIndex = (startIndexRaw && startIndexRaw <= webpub.readingOrders.length) + ? startIndexRaw + : 0; - const startTimeRaw = conv.user.params.player.current.time; - const startTime = - typeof startTimeRaw === 'number' && - startTimeRaw <= (webpub.readingOrders[startIndex].duration || Infinity) ? startTimeRaw : 0; + const startTime = (startTimeRaw && startTimeRaw <= (webpub.readingOrders[startIndex].duration || Infinity)) + ? startTimeRaw + : 0; const mediaObjects = webpub.readingOrders .map((v, i) => ({ @@ -525,46 +403,11 @@ app.handle("player", async (conv) => { // //////////////////////// -// Media PLAYET CONTEXT // +// Media PLAYER CONTEXT // // //////////////////////// -function persistMediaPlayer(conv: IConversationWithParams) { - if (conv.request.context) { - // Persist the media progress value - const _progress = conv.request.context.media?.progress || "0"; - const progress = parseInt(_progress, 10); - const index = conv.request.context.media?.index; - const url = conv.user.params.player.current.url - - ok(url, "url not defined"); - - conv.user.params.player.current.index = index; - conv.user.params.player.current.time = progress; - - if (!conv.user.params.player) { - conv.user.params.player = { - current: { - playing: false, - }, - history: new Map(), - }; - } - - conv.user.params.player.history[url] = { - index: index, - time: progress, - date: new Date().getTime(), - }; - - console.log('player persistence :'); - console.log(conv.user.params.player); - } else { - console.log('NO conv.request.context !!'); - } -} - -app.handle('reprendre_la_lecture', (conv) => { +app.handle('player__intent__resume_listening_player ', (conv) => { persistMediaPlayer(conv); // // Acknowledge pause/stop @@ -575,7 +418,7 @@ app.handle('reprendre_la_lecture', (conv) => { conv.scene.next.name = 'player'; }); -app.handle('remaining_time', async (conv) => { +app.handle('player__intent__remaining_time_player', async (conv) => { persistMediaPlayer(conv); const url = conv.user.params?.player?.current?.url; @@ -586,7 +429,7 @@ app.handle('remaining_time', async (conv) => { const webpub = await opds.webpubRequest(url); ok(webpub, 'webpub not defined'); - const index = conv.user.params.player.current.index|| 0; + const index = conv.user.params.player.current.index || 0; const time = conv.user.params.player.current.time || 0; let minutes = 0; @@ -654,6 +497,4 @@ app.handle('media_status', (conv) => { console.log('MediaStatus END'); }); - - exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app); diff --git a/webhooks/functions/src/model/storage.dto.ts b/webhooks/functions/src/model/storage.dto.ts index 95ba8883..cb0b33e7 100644 --- a/webhooks/functions/src/model/storage.dto.ts +++ b/webhooks/functions/src/model/storage.dto.ts @@ -1,13 +1,16 @@ +import * as util from 'util'; import {IStorage, IStoragePlayer, IStoragePlayerCurrent, IStoragePlayerHistory} from './storage.interface'; -import {classToPlain, Exclude, plainToClass, Type} from 'class-transformer'; -import {Equals, IsBoolean, IsDate, IsNotEmpty, IsNumber, IsObject, IsOptional, IsPositive, IsString, IsUrl, ValidateNested, validateSync} from 'class-validator'; +import {classToPlain, Exclude, plainToClass, Transform, TransformationType, Type} from 'class-transformer'; +import {Equals, IsBoolean, IsDate, IsNotEmpty, IsNumber, IsObject, IsOptional, IsString, IsUrl, Min, ValidateNested, validateSync} from 'class-validator'; const DB_VERSION = 1; class StoragePlayerHistoryDto implements IStoragePlayerHistory { + @Min(0) @IsNumber() index: number; + @Min(0) @IsNumber() time: number; @@ -22,13 +25,13 @@ class StoragePlayerHistoryDto implements IStoragePlayerHistory { } class StoragePlayerCurrentDto implements IStoragePlayerCurrent { - @IsPositive() @IsNumber() + @Min(0) @IsOptional() index?: number; - @IsPositive() @IsNumber() + @Min(0) @IsOptional() time?: number; @@ -61,7 +64,17 @@ class StoragePlayerDto implements IStoragePlayer { @IsNotEmpty() @Type(() => StoragePlayerHistoryDto) - @ValidateNested() + @Transform(({value, type}) => { // transform new Map() to plain and from plain + if (type === TransformationType.PLAIN_TO_CLASS) { + return new Map(typeof value === 'object' ? Object.entries(value) : []); + } + if (type === TransformationType.CLASS_TO_PLAIN && typeof value === 'object' && value.entries) { + return Array.from>(value.entries()).reduce((pv, [key, value]) => ({...pv, [key]: value}), {}); + } + }) + @ValidateNested({ + each: true, + }) history: Map; constructor() { @@ -109,7 +122,8 @@ export class StorageDto implements IStorage { throw new Error('bearerToken is empty'); } - console.error('Storage DTO \'create\' errors', errors); + console.error('Storage DTO \'create\' errors', util.inspect(errors, {depth: 8})); + console.error('new fresh storageDto created'); return new StorageDto(bearerToken); @@ -124,7 +138,7 @@ export class StorageDto implements IStorage { const errors = validateSync(this); if (errors.length) { - console.error('storage DTO \'extract\' errors', errors); + console.error('storage DTO \'extract\' errors', util.inspect(errors, {depth: 8})); console.error('return the last snapshot', this.snapshot); return this.snapshot; diff --git a/webhooks/functions/src/model/storage.test.ts b/webhooks/functions/src/model/storage.test.ts index fe39ca3f..9943903b 100644 --- a/webhooks/functions/src/model/storage.test.ts +++ b/webhooks/functions/src/model/storage.test.ts @@ -1,6 +1,7 @@ import 'reflect-metadata'; import {StorageDto} from './storage.dto'; import * as assert from 'assert'; +import {classToPlain} from 'class-transformer'; describe('storage DTO', () => { @@ -103,4 +104,95 @@ describe('storage DTO', () => { }, }, extr); }); + + it('good validation extract', () => { + const instance = StorageDto.create(undefined, 'test'); + + instance.player.current.index = 0; + + const extr = instance.extract(); + + assert.deepEqual({ + dbVersion: 1, + bearerToken: 'test', + player: { + current: { + index: 0, + playing: false, + }, + history: { + + }, + }, + }, extr); + }); + + it('create error', () => { + const date = new Date(); + + const obj = { + dbVersion: 1, + bearerToken: '123', + player: { + current: { + + playing: false, + }, + history: { + 'test': { + index: 0, + time: 0, + date: date, + }, + }, + }, + }; + const instance = StorageDto.create(obj, 'test'); + + assert.deepEqual(instance.player.history.get('test'), { + index: 0, + time: 0, + date: date, + }); + + instance.player.history.set('test2', { + index: 0, + time: 0, + date: date, + }); + + const extr = classToPlain(instance); + + assert.deepEqual({ + dbVersion: 1, + bearerToken: '123', + player: { + current: { + + playing: false, + }, + history: { + test2: { + index: 0, + time: 0, + date: date, + }, + test: { + index: 0, + time: 0, + date: date, + }, + }, + }, + }, extr); + + + const instance2 = StorageDto.create(extr, 'test'); + + assert.deepEqual(instance2.player.history.get('test2'), { + index: 0, + time: 0, + date: date, + }); + }); }); diff --git a/webhooks/functions/src/sdk.d.ts b/webhooks/functions/src/sdk.d.ts index 88f20316..7112477f 100644 --- a/webhooks/functions/src/sdk.d.ts +++ b/webhooks/functions/src/sdk.d.ts @@ -1 +1,4 @@ +// npm run typed:scene ; + + export type TSdkScene = 'ask_to_resume_listening_at_last_offset' | 'home_lvl1' | 'home_lvl1_AccountLinking' | 'home_members_lvl2' | 'player' | 'search' | 'select_pub_after_search' | 'select_pub_after_selection' | 'selection_lvl3'; diff --git a/webhooks/functions/src/service/listPublication.ts b/webhooks/functions/src/service/listPublication.ts new file mode 100644 index 00000000..94b765df --- /dev/null +++ b/webhooks/functions/src/service/listPublication.ts @@ -0,0 +1,26 @@ +import {TSdkScene} from '../sdk'; +import {IConversationWithParams} from '../type'; +import {getPubsFromFeed} from '../utils'; + +export async function listPublication(url: string, conv: IConversationWithParams, nextScene: TSdkScene, errorScene: TSdkScene = conv.scene.name) { + const list = await getPubsFromFeed(url); + console.log('PUBs: ', list); + + const length = list.length; + if (length > 1) { + conv.scene.next.name = nextScene; + conv.add(`Il y a ${length} publications :\n`); + + let text = ''; + list.map(({title, author}, i) => { + text += `numero ${i + 1} : ${title} ${author ? `de ${author}` : ''}\n`; + }); + conv.add(text); + } else if (length === 1) { + conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; + conv.user.params.player.current.url = list[0].webpuburl; + } else { + conv.scene.next.name = errorScene; + conv.add('aucun résultat trouvé'); + } +} diff --git a/webhooks/functions/src/service/persist.ts b/webhooks/functions/src/service/persist.ts new file mode 100644 index 00000000..964c8e8b --- /dev/null +++ b/webhooks/functions/src/service/persist.ts @@ -0,0 +1,27 @@ +import {isValidHttpUrl} from '../utils'; +import {ok} from 'assert'; +import {IConversationWithParams} from '../type'; + +export function persistMediaPlayer(conv: IConversationWithParams) { + if (!conv.request.context) { + console.log('NO conv.request.context !!'); + return; + } + + // Persist the media progress value + + const _progress = conv.request.context?.media?.progress || '0'; + const progress = parseInt(_progress, 10); + const index = conv.request.context?.media?.index || 0; + const url = conv.user.params.player.current.url; + ok(isValidHttpUrl(url), 'url not defined/valid'); + + conv.user.params.player.current.index = index; + conv.user.params.player.current.time = progress; + + conv.user.params.player.history.set(url, { + index, + time: progress, + date: new Date(), + }); +} diff --git a/webhooks/functions/src/service/selectPublication.ts b/webhooks/functions/src/service/selectPublication.ts new file mode 100644 index 00000000..11b50ead --- /dev/null +++ b/webhooks/functions/src/service/selectPublication.ts @@ -0,0 +1,24 @@ +import {IConversationWithParams} from '../type'; +import {getPubsFromFeed} from '../utils'; + +export async function selectPublication(url: string, number: number, conv: IConversationWithParams) { + const list = await getPubsFromFeed(url); + const pub = list[number - 1]; + if (!pub) { + console.log('NO PUBS found !!'); + conv.add(`Le numéro ${number} est inconnu. Veuillez choisir un autre numéro.`); + conv.scene.next.name = conv.scene.name; // loop selection or search + + return; + } + + console.log('PUB: ', pub); + + const urlWebpub = pub.webpuburl; + const history = conv.user.params.player.history.get(urlWebpub); + conv.user.params.player.current.index = history ? history.index : 0; + conv.user.params.player.current.time = history ? history.time : 0; + conv.user.params.player.current.url = urlWebpub; + + conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; +} diff --git a/webhooks/functions/src/type.ts b/webhooks/functions/src/type.ts new file mode 100644 index 00000000..d76e0c23 --- /dev/null +++ b/webhooks/functions/src/type.ts @@ -0,0 +1,35 @@ +import { ConversationV3 } from "@assistant/conversation"; +import { User, Scene } from "@assistant/conversation/dist/conversation/handler"; +import { StorageDto } from "./model/storage.dto"; +import { TSdkScene } from "./sdk"; + +export enum MediaType { + Audio = 'AUDIO', + MediaStatusACK = 'MEDIA_STATUS_ACK', + MediaTypeUnspecified = 'MEDIA_TYPE_UNSPECIFIED', +} + +export enum OptionalMediaControl { + OptionalMediaControlsUnspecified = 'OPTIONAL_MEDIA_CONTROLS_UNSPECIFIED', + Paused = 'PAUSED', + Stopped = 'STOPPED', +} + +interface IUser extends User { + params: StorageDto; +} +interface IScene extends Scene { + next: { + name: TSdkScene; + }, + name: TSdkScene; +} +export interface IConversationWithParams extends ConversationV3 { + user: IUser; + scene: IScene; + session: { + params: { + [key: string]: any; + } + } +} \ No newline at end of file diff --git a/webhooks/functions/src/utils/index.ts b/webhooks/functions/src/utils/index.ts index 593ad4b1..a428398b 100644 --- a/webhooks/functions/src/utils/index.ts +++ b/webhooks/functions/src/utils/index.ts @@ -1,18 +1,18 @@ -import { OpdsFetcher } from "opds-fetcher-parser"; -import * as assert from "assert"; -import { IOpdsLinkView } from "opds-fetcher-parser/build/src/interface/opds"; +import {OpdsFetcher} from 'opds-fetcher-parser'; +import * as assert from 'assert'; +import {IOpdsLinkView} from 'opds-fetcher-parser/build/src/interface/opds'; -export function isValidHttpUrl(string: string | undefined) { - let url: URL; +export function isValidHttpUrl(url: string | undefined): url is string { + let _url: URL; try { - if (!string) throw "" - url = new URL(string); + if (!url) return false; + _url = new URL(url); } catch (_) { return false; } - return url.protocol === 'http:' || url.protocol === 'https:'; + return _url.protocol === 'http:' || _url.protocol === 'https:'; } export async function getPubsFromFeed(url: string) { @@ -31,9 +31,9 @@ export async function getPubsFromFeed(url: string) { .slice(0, 5) .map(({title, authors, openAccessLinks}) => ({ title: title, - author: Array.isArray(authors) ? authors[0].name : "", + author: Array.isArray(authors) ? authors[0].name : '', webpuburl: (openAccessLinks as IOpdsLinkView[])[0].url, })); return list; -} \ No newline at end of file +} From d7dfd86550831c354b089d17d0de6272cea33e78 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 15 Nov 2021 17:32:32 +0100 Subject: [PATCH 022/180] fix test-webhook --- webhooks/functions/src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index cca5e46c..0fc285f6 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -131,11 +131,11 @@ app.handle('home_lvl1', (conv) => { // conv.scene.next.name }); -app.handle('home_lvl1__intent__test_webhook', (conv) => { +app.handle('test_webhook', (conv) => { conv.add('Webook works :', functions.config().debug.message || ''); console.log('TEST OK'); - conv.scene.next.name = "home_lvl1"; + conv.scene.next.name = conv.scene.name; }); app.handle('home_lvl1__intent__get_info_association_lvl1', (conv) => { From 1d59bb88d9cf532da44512509c280eec3cb9b556 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 16 Nov 2021 16:42:13 +0100 Subject: [PATCH 023/180] Selection List (PR #9) --- sdk/test/custom/scenes/home_lvl1.yaml | 2 +- sdk/test/custom/scenes/home_members_lvl2.yaml | 3 + .../select_list_after_list_selection.yaml | 58 ++++++ sdk/test/push.sh | 1 + .../webhooks/ActionsOnGoogleFulfillment.yaml | 4 +- test/dev/test/test10.ts | 3 + test/dev/test/test11.ts | 3 + test/dev/test/test9.ts | 192 +++++++++++++++++- webhooks/debug/test.js | 14 ++ webhooks/functions/package-lock.json | 28 +-- webhooks/functions/package.json | 2 +- webhooks/functions/src/index.ts | 62 ++++-- webhooks/functions/src/model/storage.dto.ts | 18 +- .../functions/src/model/storage.interface.ts | 6 + webhooks/functions/src/sdk.d.ts | 2 +- webhooks/functions/src/service/listGroups.ts | 28 +++ .../functions/src/service/listPublication.ts | 4 +- .../functions/src/service/selectGroups.ts | 21 ++ .../src/service/selectPublication.ts | 4 +- webhooks/functions/src/utils/index.ts | 19 ++ 20 files changed, 438 insertions(+), 36 deletions(-) create mode 100644 sdk/test/custom/scenes/select_list_after_list_selection.yaml create mode 100644 sdk/test/push.sh create mode 100644 webhooks/debug/test.js create mode 100644 webhooks/functions/src/service/listGroups.ts create mode 100644 webhooks/functions/src/service/selectGroups.ts diff --git a/sdk/test/custom/scenes/home_lvl1.yaml b/sdk/test/custom/scenes/home_lvl1.yaml index e5800357..e9a83216 100644 --- a/sdk/test/custom/scenes/home_lvl1.yaml +++ b/sdk/test/custom/scenes/home_lvl1.yaml @@ -12,7 +12,7 @@ intentEvents: webhookHandler: home_lvl1__intent__listen_audiobook_lvl1 intent: listen_audiobook_lvl1 - handler: - webhookHandler: home_lvl1__intent__test_webhook + webhookHandler: test_webhook intent: test_webhook onEnter: webhookHandler: home_lvl1 diff --git a/sdk/test/custom/scenes/home_members_lvl2.yaml b/sdk/test/custom/scenes/home_members_lvl2.yaml index ab947af9..109b5a28 100644 --- a/sdk/test/custom/scenes/home_members_lvl2.yaml +++ b/sdk/test/custom/scenes/home_members_lvl2.yaml @@ -16,5 +16,8 @@ intentEvents: webhookHandler: test_player_sdk intent: test_player_sdk transitionToScene: home_members_lvl2 +- handler: + webhookHandler: test_webhook + intent: test_webhook onEnter: webhookHandler: home_members_lvl2 diff --git a/sdk/test/custom/scenes/select_list_after_list_selection.yaml b/sdk/test/custom/scenes/select_list_after_list_selection.yaml new file mode 100644 index 00000000..6bbfee5c --- /dev/null +++ b/sdk/test/custom/scenes/select_list_after_list_selection.yaml @@ -0,0 +1,58 @@ +intentEvents: +- handler: + staticPrompt: + candidates: + - promptResponse: + firstSimple: + variants: + - speech: je n’ai pas compris le numéro, merci de le répêter + intent: actions.intent.NO_MATCH_1 +- handler: + staticPrompt: + candidates: + - promptResponse: + firstSimple: + variants: + - speech: je n’ai pas compris le numéro, dite un numéro + intent: actions.intent.NO_MATCH_2 +- handler: + staticPrompt: + candidates: + - promptResponse: + firstSimple: + variants: + - speech: je n’ai pas compris le numéro, dite un numéro + intent: actions.intent.NO_MATCH_FINAL +- handler: + staticPrompt: + candidates: + - promptResponse: + firstSimple: + variants: + - speech: je n’ai pas compris le numéro, dite un numéro + intent: actions.intent.NO_INPUT_1 +- handler: + staticPrompt: + candidates: + - promptResponse: + firstSimple: + variants: + - speech: je n’ai pas compris le numéro, dite un numéro + intent: actions.intent.NO_INPUT_2 +- handler: + staticPrompt: + candidates: + - promptResponse: + firstSimple: + variants: + - speech: je n’ai pas compris le numéro + intent: actions.intent.NO_INPUT_FINAL +onEnter: + webhookHandler: select_list_after_list_selection +onSlotUpdated: + webhookHandler: select_list_after_list_selection__slot__number +slots: +- name: number + required: true + type: + name: actions.type.Number diff --git a/sdk/test/push.sh b/sdk/test/push.sh new file mode 100644 index 00000000..75909f98 --- /dev/null +++ b/sdk/test/push.sh @@ -0,0 +1 @@ +gactions push diff --git a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml index ed1a3b4d..e602df67 100644 --- a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml @@ -9,7 +9,6 @@ handlers: - name: home_lvl1__intent__enter_member_space_lvl1 - name: home_lvl1__intent__resume_listening_player - name: home_lvl1__intent__get_info_association_lvl1 -- name: home_lvl1__intent__test_webhook - name: home_lvl1__intent__listen_audiobook_lvl1 - name: home_members_lvl2 - name: home_members_lvl2__intent__listen_audiobook_lvl2 @@ -22,6 +21,8 @@ handlers: - name: select_pub_after_selection - name: select_pub_after_selection__slot__number - name: select_pub_after_selection__intent__resume_listening_player +- name: select_list_after_list_selection +- name: select_list_after_list_selection__slot__number - name: ask_to_resume_listening_at_last_offset__intent__yes - name: player__intent__resume_listening_player - name: player__intent__remaining_time_player @@ -33,6 +34,7 @@ handlers: - name: select_pub_after_search - name: test_player_sdk - name: test_setup_sdk +- name: test_webhook httpsEndpoint: baseUrl: https://us-central1-valentin-5.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/test/dev/test/test10.ts b/test/dev/test/test10.ts index 20d2ee7f..a60119a5 100644 --- a/test/dev/test/test10.ts +++ b/test/dev/test/test10.ts @@ -29,7 +29,10 @@ describe('My Action Test Suite', function () { test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre, Que voulez-vous faire ?`); await test.sendQuery(`selections thématiques`); + test.assertSpeech(``); + await test.sendQuery(`numéro 2`); + // // resp = test.getLatestResponse(); diff --git a/test/dev/test/test11.ts b/test/dev/test/test11.ts index b34cb219..d68dc9c9 100644 --- a/test/dev/test/test11.ts +++ b/test/dev/test/test11.ts @@ -30,6 +30,9 @@ describe('My Action Test Suite', function () { await test.sendQuery(`selections par genre`); + test.assertSpeech(``); + + await test.sendQuery(`numéro 2`); // // resp = test.getLatestResponse(); diff --git a/test/dev/test/test9.ts b/test/dev/test/test9.ts index 7fcd9ca1..5c02c18e 100644 --- a/test/dev/test/test9.ts +++ b/test/dev/test/test9.ts @@ -29,6 +29,196 @@ describe('My Action Test Suite', function () { test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre, Que voulez-vous faire ?`); await test.sendQuery(`ma liste`); + test.assertSpeech(`J’ai trouvé 2 publications. Pour choisir une publication dites son numéro:`); + + await test.sendQuery(`2`); + + const media = test.getMedia(); + // fs.writeFileSync('/tmp/media.json', JSON.stringify(media)); + chai.expect(media).to.deep.equal({ + "optionalMediaControls": [ + "PAUSED", + "STOPPED" + ], + "mediaObjects": [ + { + "name": "Thérèse Raquin - 1", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap01-03.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 2", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap04-06.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 3", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap07-09.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 4", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap10-12.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 5", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap13-16.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 6", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap17-18.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 7", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap19-20.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 8", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap21-22.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 9", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap23-25.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 10", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap26-27.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 11", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap28-29.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + }, + { + "name": "Thérèse Raquin - 12", + "description": "", + "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap30-32.mp3", + "image": { + "large": { + "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", + "alt": "Thérèse Raquin", + "height": 0, + "width": 0 + }, + "image": "large" + } + } + ], + "startOffset": { + "seconds": "0", + "nanos": 0 + }, + "mediaType": "AUDIO" + }); + + + // @@ -37,7 +227,7 @@ describe('My Action Test Suite', function () { before('before all', async () => { // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); + test = new ActionsOnGoogleTestManager({ projectId: PROJECT_ID }); await test.writePreviewFromDraft(); test.setSuiteLocale(DEFAULT_LOCALE); test.setSuiteSurface(DEFAULT_SURFACE); diff --git a/webhooks/debug/test.js b/webhooks/debug/test.js new file mode 100644 index 00000000..0f73022d --- /dev/null +++ b/webhooks/debug/test.js @@ -0,0 +1,14 @@ + +const opds = require('opds-fetcher-parser'); +const fs = require('fs'); + +(async function () { + + const o = new opds.OpdsFetcher(); + + const feed = await o.feedRequest("https://storage.googleapis.com/audiobook_edrlab/navigation/thematic_list.json"); + + console.log(feed); + fs.writeFileSync("/tmp/feed.json", JSON.stringify(feed)); + +})() \ No newline at end of file diff --git a/webhooks/functions/package-lock.json b/webhooks/functions/package-lock.json index fd419bdc..52603dac 100644 --- a/webhooks/functions/package-lock.json +++ b/webhooks/functions/package-lock.json @@ -773,9 +773,9 @@ "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" }, "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", "requires": { "safer-buffer": "~2.1.0" } @@ -828,9 +828,9 @@ } }, "big-integer": { - "version": "1.6.50", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.50.tgz", - "integrity": "sha512-+O2uoQWFRo8ysZNo/rjtri2jIwjr3XfeAgRjAUADRqGG+ZITvyn8J1kvXLTaKVr3hhGXk+f23tKfdzmklVM9vQ==" + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==" }, "bignumber.js": { "version": "9.0.1", @@ -2817,8 +2817,8 @@ } }, "opds-fetcher-parser": { - "version": "github:panaC/opds_fetcher_parser#efec695f50b386071ccf935396f0a8ea4750c9ae", - "from": "github:panaC/opds_fetcher_parser#efec695f50b386071ccf935396f0a8ea4750c9ae", + "version": "github:panaC/opds_fetcher_parser#46f59a92513c17a060d02dfceb82633bbbbc4be3", + "from": "github:panaC/opds_fetcher_parser#46f59a92513c17a060d02dfceb82633bbbbc4be3", "requires": { "moment": "^2.29.1", "nanoid": "^3.1.23", @@ -3060,9 +3060,9 @@ } }, "r2-opds-js": { - "version": "1.0.37", - "resolved": "https://registry.npmjs.org/r2-opds-js/-/r2-opds-js-1.0.37.tgz", - "integrity": "sha512-7LEG7S9RBJ94MfYTy5+sCDnbA5qf4a3qSoxTYWorSac7MRyjkZdRusWkUl7LW438t78wnPCx3TDeYowXVVDOrw==", + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/r2-opds-js/-/r2-opds-js-1.0.38.tgz", + "integrity": "sha512-yZB1BFmfrxgvIIe1t+p7nWrMcSS+8ge9NJIDaPe1Zq6rHpC8IlBy5HvdCgGN6pX7Ix1u3VbI1zy/KxVFUPzAsg==", "requires": { "debug": "^4.3.2", "r2-lcp-js": "^1.0.33", @@ -3397,9 +3397,9 @@ "dev": true }, "slugify": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.1.tgz", - "integrity": "sha512-5ofqMTbetNhxlzjYYLBaZFQd6oiTuSkQlyfPEFIMwgUABlZQ0hbk5xIV9Ydd5jghWeRoO7GkiJliUvTpLOjNRA==" + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.2.tgz", + "integrity": "sha512-XMtI8qD84LwCpthLMBHlIhcrj10cgA+U/Ot8G6FD6uFuWZtMfKK75JO7l81nzpFJsPlsW6LT+VKqWQJW3+6New==" }, "snakeize": { "version": "0.1.0", diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index 9db66969..13be34bb 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -22,7 +22,7 @@ "class-validator": "^0.13.1", "firebase-admin": "^9.8.0", "firebase-functions": "^3.16.0", - "opds-fetcher-parser": "github:panaC/opds_fetcher_parser#efec695f50b386071ccf935396f0a8ea4750c9ae", + "opds-fetcher-parser": "github:panaC/opds_fetcher_parser#46f59a92513c17a060d02dfceb82633bbbbc4be3", "reflect-metadata": "^0.1.13" }, "devDependencies": { diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 0fc285f6..7ca4a9e6 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -13,11 +13,14 @@ import { persistMediaPlayer } from "./service/persist"; import { listPublication } from "./service/listPublication"; import { selectPublication } from "./service/selectPublication"; import { testConversation } from "./conversation/test"; +import { listGroups } from "./service/listGroups"; +import { selectGroup } from "./service/selectGroups"; const BEARER_TOKEN_NOT_DEFINED = "bearer token not defined"; -const WEBPUB_URL = 'https://storage.googleapis.com/audiobook_edrlab/webpub/'; const SELECTION_URL = 'https://storage.googleapis.com/audiobook_edrlab/groups/popular.json'; const SEARCH_URL = 'https://europe-west1-audiobooks-a6348.cloudfunctions.net/indexer?url=https://storage.googleapis.com/audiobook_edrlab/navigation/all.json&query={query}'; +const THEMATIC_LIST_URL = 'https://storage.googleapis.com/audiobook_edrlab/navigation/thematic_list.json'; +const GENRE_LIST_URL = 'https://storage.googleapis.com/audiobook_edrlab/navigation/genre_list.json'; const app = conversation(); export type TApp = typeof app; @@ -199,27 +202,42 @@ app.handle('selection_lvl3', (conv) => { conv.add("Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre, Que voulez-vous faire ?") + // reset selection context + conv.user.params.selection.url = undefined; + conv.user.params.selection.topUrl = undefined; + // wait intent // conv.scene.next.name }); -app.handle('selection_lvl3__intent__selection_genre_lvl3', (conv) => { +app.handle('selection_lvl3__intent__selection_genre_lvl3', async (conv) => { - conv.add("sélection par genre"); + // conv.add("sélection par genre"); - conv.scene.next.name = "home_members_lvl2"; + const url = GENRE_LIST_URL; + conv.user.params.selection.topUrl = url; + conv.user.params.selection.url = undefined; + + await listGroups(url, conv, 'select_list_after_list_selection'); }); -app.handle('selection_lvl3__intent__selection_thematic_list_lvl3', (conv) => { +app.handle('selection_lvl3__intent__selection_thematic_list_lvl3', async (conv) => { conv.add('sélection par liste thématique'); - conv.scene.next.name = "home_members_lvl2"; + const url = THEMATIC_LIST_URL; + conv.user.params.selection.topUrl = url; + conv.user.params.selection.url = undefined; + + await listGroups(url, conv, 'select_list_after_list_selection'); }); app.handle('selection_lvl3__intent__selection_my_list_lvl3', async (conv) => { const url = SELECTION_URL; + conv.user.params.selection.topUrl = undefined; + conv.user.params.selection.url = url; + await listPublication(url, conv, 'select_pub_after_selection', 'home_members_lvl2'); console.log('selection_my_list_lvl3 EXIT'); @@ -232,12 +250,34 @@ app.handle('select_pub_after_selection', (conv) => { // wait slot number or intent }); +app.handle('select_list_after_list_selection', (conv) => { + + conv.add("Pour choisir une sélection dite son numéro"); + + // wait slot number or intent +}); + +app.handle('select_list_after_list_selection__slot__number', async (conv) => { + console.log('select_publication_number START'); + + const number = conv.intent.params?.number.resolved; + + const url = conv.user.params.selection.topUrl; + + ok(url, "selection list url not defined"); + await selectGroup(url, number, conv); + + console.log('select_publication_number END'); +}); + + app.handle('select_pub_after_selection__slot__number', async (conv) => { console.log('select_publication_number START'); const number = conv.intent.params?.number.resolved; - const url = SELECTION_URL; + const url = conv.user.params.selection.url; + ok(url, "no selection url available"); await selectPublication(url, number, conv); console.log('select_publication_number END'); @@ -298,13 +338,7 @@ app.handle('search__slot__query', async (conv) => { console.log('search_livre_lvl2 START'); - let query = null; - try { - query = conv.intent.params?.query.resolved; - } catch (_) { - // ignore - } - + const query = conv.intent.params?.query.resolved; ok(typeof query === 'string', 'aucune requete demandée'); conv.session.params.query = query; diff --git a/webhooks/functions/src/model/storage.dto.ts b/webhooks/functions/src/model/storage.dto.ts index cb0b33e7..be6eed10 100644 --- a/webhooks/functions/src/model/storage.dto.ts +++ b/webhooks/functions/src/model/storage.dto.ts @@ -1,5 +1,5 @@ import * as util from 'util'; -import {IStorage, IStoragePlayer, IStoragePlayerCurrent, IStoragePlayerHistory} from './storage.interface'; +import {IStorage, IStoragePlayer, IStoragePlayerCurrent, IStoragePlayerHistory, IStorageSelection} from './storage.interface'; import {classToPlain, Exclude, plainToClass, Transform, TransformationType, Type} from 'class-transformer'; import {Equals, IsBoolean, IsDate, IsNotEmpty, IsNumber, IsObject, IsOptional, IsString, IsUrl, Min, ValidateNested, validateSync} from 'class-validator'; @@ -83,6 +83,16 @@ class StoragePlayerDto implements IStoragePlayer { } } +class StorageSelectionDto implements IStorageSelection { + @IsOptional() + @IsUrl() + topUrl?: string; + + @IsOptional() + @IsUrl() + url?: string; +} + export class StorageDto implements IStorage { @IsNumber() @Equals(DB_VERSION) @@ -97,6 +107,12 @@ export class StorageDto implements IStorage { @ValidateNested() player: StoragePlayerDto; + @IsObject() + @IsNotEmpty() + @Type(() => StorageSelectionDto) + @ValidateNested() + selection: StorageSelectionDto; + @Exclude() snapshot: IStorage; diff --git a/webhooks/functions/src/model/storage.interface.ts b/webhooks/functions/src/model/storage.interface.ts index 561d489b..f75e5276 100644 --- a/webhooks/functions/src/model/storage.interface.ts +++ b/webhooks/functions/src/model/storage.interface.ts @@ -17,8 +17,14 @@ export interface IStoragePlayer { history: Map; } +export interface IStorageSelection { + topUrl?: string; + url?: string; +} + export interface IStorage { bearerToken: string; + selection: IStorageSelection; player: IStoragePlayer; } diff --git a/webhooks/functions/src/sdk.d.ts b/webhooks/functions/src/sdk.d.ts index 7112477f..ae535c9e 100644 --- a/webhooks/functions/src/sdk.d.ts +++ b/webhooks/functions/src/sdk.d.ts @@ -1,4 +1,4 @@ // npm run typed:scene ; -export type TSdkScene = 'ask_to_resume_listening_at_last_offset' | 'home_lvl1' | 'home_lvl1_AccountLinking' | 'home_members_lvl2' | 'player' | 'search' | 'select_pub_after_search' | 'select_pub_after_selection' | 'selection_lvl3'; +export type TSdkScene = 'ask_to_resume_listening_at_last_offset' | 'home_lvl1' | 'home_lvl1_AccountLinking' | 'home_members_lvl2' | 'player' | 'search' | 'select_list_after_list_selection' | 'select_pub_after_search' | 'select_pub_after_selection' | 'selection_lvl3'; diff --git a/webhooks/functions/src/service/listGroups.ts b/webhooks/functions/src/service/listGroups.ts new file mode 100644 index 00000000..dff57a2a --- /dev/null +++ b/webhooks/functions/src/service/listGroups.ts @@ -0,0 +1,28 @@ +import {TSdkScene} from '../sdk'; +import {IConversationWithParams} from '../type'; +import {getGroupsFromFeed, isValidHttpUrl} from '../utils'; +import {ok} from 'assert'; + +export async function listGroups(url: string, conv: IConversationWithParams, nextScene: TSdkScene, errorScene: TSdkScene = conv.scene.name) { + ok(isValidHttpUrl(url), 'url not valid'); + const list = await getGroupsFromFeed(url); + console.log('SELECTIONS: ', list); + + const length = list.length; + if (length > 1) { + conv.scene.next.name = nextScene; + conv.add(`Il y a ${length} sélections :\n`); + + let text = ''; + list.map(({title}, i) => { + text += `numero ${i + 1} : ${title}\n`; + }); + conv.add(text); + } else if (length === 1) { + conv.scene.next.name = 'select_pub_after_selection'; + conv.user.params.selection.url = list[0].groupUrl; + } else { + conv.scene.next.name = errorScene; + conv.add('aucun résultat trouvé'); + } +} diff --git a/webhooks/functions/src/service/listPublication.ts b/webhooks/functions/src/service/listPublication.ts index 94b765df..30fe7f32 100644 --- a/webhooks/functions/src/service/listPublication.ts +++ b/webhooks/functions/src/service/listPublication.ts @@ -1,8 +1,10 @@ import {TSdkScene} from '../sdk'; import {IConversationWithParams} from '../type'; -import {getPubsFromFeed} from '../utils'; +import {getPubsFromFeed, isValidHttpUrl} from '../utils'; +import {ok} from 'assert'; export async function listPublication(url: string, conv: IConversationWithParams, nextScene: TSdkScene, errorScene: TSdkScene = conv.scene.name) { + ok(isValidHttpUrl(url), 'url not valid'); const list = await getPubsFromFeed(url); console.log('PUBs: ', list); diff --git a/webhooks/functions/src/service/selectGroups.ts b/webhooks/functions/src/service/selectGroups.ts new file mode 100644 index 00000000..4c2e4d80 --- /dev/null +++ b/webhooks/functions/src/service/selectGroups.ts @@ -0,0 +1,21 @@ +import {IConversationWithParams} from '../type'; +import {getGroupsFromFeed, isValidHttpUrl} from '../utils'; +import {ok} from 'assert'; + +export async function selectGroup(url: string, number: number, conv: IConversationWithParams) { + ok(isValidHttpUrl(url), 'url not valid'); + const list = await getGroupsFromFeed(url); + const group = list[number - 1]; + if (!group) { + console.log('NO GROUPS found !!'); + conv.add(`Le numéro ${number} est inconnu. Veuillez choisir un autre numéro.`); + conv.scene.next.name = conv.scene.name; // loop selection or search + + return; + } + + console.log('Groups: ', group); + + conv.user.params.selection.url = group.groupUrl; + conv.scene.next.name = 'select_pub_after_selection'; +} diff --git a/webhooks/functions/src/service/selectPublication.ts b/webhooks/functions/src/service/selectPublication.ts index 11b50ead..f0cc2686 100644 --- a/webhooks/functions/src/service/selectPublication.ts +++ b/webhooks/functions/src/service/selectPublication.ts @@ -1,7 +1,9 @@ import {IConversationWithParams} from '../type'; -import {getPubsFromFeed} from '../utils'; +import {getPubsFromFeed, isValidHttpUrl} from '../utils'; +import {ok} from 'assert'; export async function selectPublication(url: string, number: number, conv: IConversationWithParams) { + ok(isValidHttpUrl(url), 'url not valid'); const list = await getPubsFromFeed(url); const pub = list[number - 1]; if (!pub) { diff --git a/webhooks/functions/src/utils/index.ts b/webhooks/functions/src/utils/index.ts index a428398b..bbf1bcad 100644 --- a/webhooks/functions/src/utils/index.ts +++ b/webhooks/functions/src/utils/index.ts @@ -37,3 +37,22 @@ export async function getPubsFromFeed(url: string) { return list; } + +export async function getGroupsFromFeed(url: string) { + const opds = new OpdsFetcher(); + const feed = await opds.feedRequest(url); + + assert.ok(Array.isArray(feed.groups), 'no groups'); + const list = feed.groups + .filter(({selfLink: l}) /* : l is IOpdsLinkView[]*/ => { + return l?.title && l?.url && isValidHttpUrl(l.url); + }) + .slice(0, 5) + .map(({selfLink: {title, url}}) => ({ + title: title, + groupUrl: url, + })); + + return list; +} + From 79a08768f7f8564846ad47cabafca25721fcafc1 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 16 Nov 2021 16:59:25 +0100 Subject: [PATCH 024/180] fix: storageDto --- webhooks/functions/src/model/storage.dto.ts | 1 + webhooks/functions/src/model/storage.test.ts | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/webhooks/functions/src/model/storage.dto.ts b/webhooks/functions/src/model/storage.dto.ts index be6eed10..034063b9 100644 --- a/webhooks/functions/src/model/storage.dto.ts +++ b/webhooks/functions/src/model/storage.dto.ts @@ -121,6 +121,7 @@ export class StorageDto implements IStorage { this.bearerToken = bearerToken; this.player = new StoragePlayerDto(); this.snapshot = classToPlain(this) as IStorage; + this.selection = new StorageSelectionDto(); } @Exclude() diff --git a/webhooks/functions/src/model/storage.test.ts b/webhooks/functions/src/model/storage.test.ts index 9943903b..3916f6ee 100644 --- a/webhooks/functions/src/model/storage.test.ts +++ b/webhooks/functions/src/model/storage.test.ts @@ -18,6 +18,7 @@ describe('storage DTO', () => { }, }, + selection: {} }; assert.throws(() => StorageDto.create(obj)); @@ -36,6 +37,7 @@ describe('storage DTO', () => { }, }, + selection: {} }; const instance = StorageDto.create(obj); @@ -57,6 +59,7 @@ describe('storage DTO', () => { history: { }, + selection: {} }, }; @@ -80,6 +83,7 @@ describe('storage DTO', () => { }, }, + selection: {} }, extr); }); @@ -102,6 +106,7 @@ describe('storage DTO', () => { }, }, + // selection: {} }, extr); }); @@ -124,7 +129,13 @@ describe('storage DTO', () => { }, }, + selection: {} }, extr); + + const instance2 = StorageDto.create(extr); + + assert.deepEqual(instance2.selection, {}); + assert.deepEqual(instance2.selection.url, undefined); }); it('create error', () => { @@ -146,6 +157,7 @@ describe('storage DTO', () => { }, }, }, + selection: {} }; const instance = StorageDto.create(obj, 'test'); @@ -184,6 +196,7 @@ describe('storage DTO', () => { }, }, }, + selection: {} }, extr); From 61a229fef300d671c6bf0b4adb7fa3c24908bbb7 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 16 Nov 2021 18:22:09 +0100 Subject: [PATCH 025/180] fix: selection --- webhooks/functions/src/index.ts | 13 +++-- webhooks/functions/src/model/storage.dto.ts | 2 +- webhooks/functions/src/model/storage.test.ts | 49 +++++++++++++++---- .../functions/src/service/selectGroups.ts | 2 +- 4 files changed, 50 insertions(+), 16 deletions(-) diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 7ca4a9e6..d2d40c40 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -223,7 +223,7 @@ app.handle('selection_lvl3__intent__selection_genre_lvl3', async (conv) => { app.handle('selection_lvl3__intent__selection_thematic_list_lvl3', async (conv) => { - conv.add('sélection par liste thématique'); + // conv.add('sélection par liste thématique'); const url = THEMATIC_LIST_URL; conv.user.params.selection.topUrl = url; @@ -262,10 +262,15 @@ app.handle('select_list_after_list_selection__slot__number', async (conv) => { const number = conv.intent.params?.number.resolved; - const url = conv.user.params.selection.topUrl; + const topUrl = conv.user.params.selection.topUrl; - ok(url, "selection list url not defined"); - await selectGroup(url, number, conv); + ok(topUrl, "selection list url not defined"); + await selectGroup(topUrl, number, conv); + + const url = conv.user.params.selection.url; + + ok(url, 'selection url not defined'); + await listPublication(url, conv, 'select_pub_after_selection'); console.log('select_publication_number END'); }); diff --git a/webhooks/functions/src/model/storage.dto.ts b/webhooks/functions/src/model/storage.dto.ts index 034063b9..de8f5a17 100644 --- a/webhooks/functions/src/model/storage.dto.ts +++ b/webhooks/functions/src/model/storage.dto.ts @@ -161,7 +161,7 @@ export class StorageDto implements IStorage { return this.snapshot; } - const storage = classToPlain(this); + const storage = classToPlain(this, {exposeUnsetFields: false}); return storage; } } diff --git a/webhooks/functions/src/model/storage.test.ts b/webhooks/functions/src/model/storage.test.ts index 3916f6ee..b79f51bc 100644 --- a/webhooks/functions/src/model/storage.test.ts +++ b/webhooks/functions/src/model/storage.test.ts @@ -18,7 +18,7 @@ describe('storage DTO', () => { }, }, - selection: {} + selection: {}, }; assert.throws(() => StorageDto.create(obj)); @@ -37,7 +37,7 @@ describe('storage DTO', () => { }, }, - selection: {} + selection: {}, }; const instance = StorageDto.create(obj); @@ -59,7 +59,7 @@ describe('storage DTO', () => { history: { }, - selection: {} + selection: {}, }, }; @@ -83,7 +83,7 @@ describe('storage DTO', () => { }, }, - selection: {} + selection: {}, }, extr); }); @@ -108,12 +108,18 @@ describe('storage DTO', () => { }, // selection: {} }, extr); + + const instance2 = StorageDto.create(extr); + + assert.deepEqual(instance2.selection, {}); + assert.deepEqual(instance2.selection.url, undefined); }); - it('good validation extract', () => { + it('selection validation extract', () => { const instance = StorageDto.create(undefined, 'test'); - instance.player.current.index = 0; + instance.selection.url = undefined; + // instance.selection.topUrl = "http://google.com"; const extr = instance.extract(); @@ -122,14 +128,14 @@ describe('storage DTO', () => { bearerToken: 'test', player: { current: { - index: 0, + playing: false, }, history: { }, }, - selection: {} + selection: {}, }, extr); const instance2 = StorageDto.create(extr); @@ -138,6 +144,29 @@ describe('storage DTO', () => { assert.deepEqual(instance2.selection.url, undefined); }); + it('good validation extract', () => { + const instance = StorageDto.create(undefined, 'test'); + + instance.player.current.index = 0; + + const extr = instance.extract(); + + assert.deepEqual({ + dbVersion: 1, + bearerToken: 'test', + player: { + current: { + index: 0, + playing: false, + }, + history: { + + }, + }, + selection: {}, + }, extr); + }); + it('create error', () => { const date = new Date(); @@ -157,7 +186,7 @@ describe('storage DTO', () => { }, }, }, - selection: {} + selection: {}, }; const instance = StorageDto.create(obj, 'test'); @@ -196,7 +225,7 @@ describe('storage DTO', () => { }, }, }, - selection: {} + selection: {}, }, extr); diff --git a/webhooks/functions/src/service/selectGroups.ts b/webhooks/functions/src/service/selectGroups.ts index 4c2e4d80..cb98ccd0 100644 --- a/webhooks/functions/src/service/selectGroups.ts +++ b/webhooks/functions/src/service/selectGroups.ts @@ -17,5 +17,5 @@ export async function selectGroup(url: string, number: number, conv: IConversati console.log('Groups: ', group); conv.user.params.selection.url = group.groupUrl; - conv.scene.next.name = 'select_pub_after_selection'; + // conv.scene.next.name = 'select_pub_after_selection'; } From aca5d4e9c2bc9af78f9c44890286788049834f0a Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 17 Nov 2021 15:47:13 +0100 Subject: [PATCH 026/180] fix: reset user storage at the end --- webhooks/functions/src/index.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index d2d40c40..f14f3882 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -32,9 +32,9 @@ app.handle = (path, fn) => { await Promise.resolve(fn(conv)); + const bearerToken = conv.user.params.bearerToken; try { - const bearerToken = conv.user.params.bearerToken; ok(bearerToken, "bearerToken not defined"); ok(bearerToken !== BEARER_TOKEN_NOT_DEFINED, "bearerToken not defined") @@ -50,6 +50,14 @@ app.handle = (path, fn) => { console.log(conv.user.params); console.log("----------"); + + // reset user storage + // @ts-ignore + conv.user.params = { + bearerToken, + }; + + }); return ret; @@ -186,7 +194,7 @@ app.handle('home_members_lvl2__intent__listen_audiobook_lvl2', (conv) => { app.handle('home_members_lvl2__intent__resume_audiobook_lvl2', (conv) => { const url = conv.user.params.player.current.url; - if (!url) { + if (!isValidHttpUrl(url)) { conv.scene.next.name = "home_members_lvl2"; conv.add("aucune lecture en cours"); } else From a7764dff00e7d3d4cccc79426eacf7d983e43e6f Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 17 Nov 2021 16:57:27 +0100 Subject: [PATCH 027/180] test: test update --- test/dev/test/constant.ts | 2 +- test/dev/test/test1.ts | 3 --- test/dev/test/test10.ts | 2 +- test/dev/test/test11.ts | 2 +- test/dev/test/test2.ts | 4 ++-- test/dev/test/test3.ts | 2 +- test/dev/test/test4.ts | 2 +- test/dev/test/test5.ts | 2 +- test/dev/test/test6.ts | 2 +- test/dev/test/test7.ts | 2 +- test/dev/test/test8.ts | 2 +- test/dev/test/test9.ts | 2 +- 12 files changed, 12 insertions(+), 15 deletions(-) diff --git a/test/dev/test/constant.ts b/test/dev/test/constant.ts index d2e9e76d..d7671179 100644 --- a/test/dev/test/constant.ts +++ b/test/dev/test/constant.ts @@ -5,7 +5,7 @@ import {ok} from 'assert'; export const DEFAULT_LOCALE = 'fr-FR'; export const DEFAULT_SURFACE = 'PHONE'; export const HOME_PROMPT = "Bienvenue dans l'application d'écoute de livre audio valentin hauy"; -export const MEMBER_PROMPT = "Bienvenue dans l'espace membres. Les commandes possibles sont, sélection, lecture, recherche. Que voulez-vous faire ?"; +export const MEMBER_PROMPT = "Bienvenue dans l'espace membres. Les commandes possibles sont: sélection, lecture, recherche. Que voulez-vous faire ?"; export const PROJECT_ID = env['PROJECT_ID'] || ''; export const TRIGGER_PHRASE = 'Parler avec valentin audio dev'; diff --git a/test/dev/test/test1.ts b/test/dev/test/test1.ts index 9f9beb27..fe7185ed 100644 --- a/test/dev/test/test1.ts +++ b/test/dev/test/test1.ts @@ -1,8 +1,6 @@ import 'mocha'; import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; const TEST_NUM = 1; @@ -15,7 +13,6 @@ describe('My Action Test Suite', function () { async function startConversation() { await test.sendQuery(TRIGGER_PHRASE); test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); test.assertIntent('actions.intent.MAIN'); test.assertScene('home_members_lvl2'); diff --git a/test/dev/test/test10.ts b/test/dev/test/test10.ts index a60119a5..4c4eedcd 100644 --- a/test/dev/test/test10.ts +++ b/test/dev/test/test10.ts @@ -17,7 +17,7 @@ describe('My Action Test Suite', function () { async function startConversation() { await test.sendQuery(TRIGGER_PHRASE); test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); test.assertIntent('actions.intent.MAIN'); test.assertScene('home_members_lvl2'); diff --git a/test/dev/test/test11.ts b/test/dev/test/test11.ts index d68dc9c9..8fed11f7 100644 --- a/test/dev/test/test11.ts +++ b/test/dev/test/test11.ts @@ -17,7 +17,7 @@ describe('My Action Test Suite', function () { async function startConversation() { await test.sendQuery(TRIGGER_PHRASE); test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); test.assertIntent('actions.intent.MAIN'); test.assertScene('home_members_lvl2'); diff --git a/test/dev/test/test2.ts b/test/dev/test/test2.ts index d21e91e0..670fd1c6 100644 --- a/test/dev/test/test2.ts +++ b/test/dev/test/test2.ts @@ -15,7 +15,7 @@ describe('My Action Test Suite', function () { async function startConversation() { await test.sendQuery(TRIGGER_PHRASE); test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); test.assertIntent('actions.intent.MAIN'); test.assertScene('home_members_lvl2'); @@ -29,7 +29,7 @@ describe('My Action Test Suite', function () { test.assertSpeech(`Que voulez-vous écouter ?`); - await test.sendQuery('test avec aucune publication renvoyés'); + await test.sendQuery('test avec aucune publication renvoyées'); await test.assertSpeech(`aucun résultat trouvé Que voulez-vous écouter ? Par exemple Zola`); diff --git a/test/dev/test/test3.ts b/test/dev/test/test3.ts index 8881eda1..33eba27e 100644 --- a/test/dev/test/test3.ts +++ b/test/dev/test/test3.ts @@ -15,7 +15,7 @@ describe('My Action Test Suite', function () { async function startConversation() { await test.sendQuery(TRIGGER_PHRASE); test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); test.assertIntent('actions.intent.MAIN'); test.assertScene('home_members_lvl2'); diff --git a/test/dev/test/test4.ts b/test/dev/test/test4.ts index dd7ef58f..c7980423 100644 --- a/test/dev/test/test4.ts +++ b/test/dev/test/test4.ts @@ -17,7 +17,7 @@ describe('My Action Test Suite', function () { async function startConversation() { await test.sendQuery(TRIGGER_PHRASE); test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); test.assertIntent('actions.intent.MAIN'); test.assertScene('home_members_lvl2'); diff --git a/test/dev/test/test5.ts b/test/dev/test/test5.ts index a1b41361..e5ee93bb 100644 --- a/test/dev/test/test5.ts +++ b/test/dev/test/test5.ts @@ -17,7 +17,7 @@ describe('My Action Test Suite', function () { async function startConversation() { await test.sendQuery(TRIGGER_PHRASE); test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); test.assertIntent('actions.intent.MAIN'); test.assertScene('home_members_lvl2'); diff --git a/test/dev/test/test6.ts b/test/dev/test/test6.ts index 3cded290..68455b5f 100644 --- a/test/dev/test/test6.ts +++ b/test/dev/test/test6.ts @@ -17,7 +17,7 @@ describe('My Action Test Suite', function () { async function startConversation() { await test.sendQuery(TRIGGER_PHRASE); test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); test.assertIntent('actions.intent.MAIN'); test.assertScene('home_members_lvl2'); diff --git a/test/dev/test/test7.ts b/test/dev/test/test7.ts index 35836d0f..ba94d6b2 100644 --- a/test/dev/test/test7.ts +++ b/test/dev/test/test7.ts @@ -17,7 +17,7 @@ describe('My Action Test Suite', function () { async function startConversation() { await test.sendQuery(TRIGGER_PHRASE); test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); test.assertIntent('actions.intent.MAIN'); test.assertScene('home_members_lvl2'); diff --git a/test/dev/test/test8.ts b/test/dev/test/test8.ts index 1fa173db..adba62e2 100644 --- a/test/dev/test/test8.ts +++ b/test/dev/test/test8.ts @@ -17,7 +17,7 @@ describe('My Action Test Suite', function () { async function startConversation() { await test.sendQuery(TRIGGER_PHRASE); test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); test.assertIntent('actions.intent.MAIN'); test.assertScene('home_members_lvl2'); diff --git a/test/dev/test/test9.ts b/test/dev/test/test9.ts index 5c02c18e..f6531f26 100644 --- a/test/dev/test/test9.ts +++ b/test/dev/test/test9.ts @@ -17,7 +17,7 @@ describe('My Action Test Suite', function () { async function startConversation() { await test.sendQuery(TRIGGER_PHRASE); test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); test.assertIntent('actions.intent.MAIN'); test.assertScene('home_members_lvl2'); From 2efe3820593169cb22322beccb0062485c394ee5 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 17 Nov 2021 18:16:21 +0100 Subject: [PATCH 028/180] fix: firestore timestamp format --- webhooks/functions/src/index.ts | 7 +++---- webhooks/functions/src/model/storage.dto.ts | 10 ++++++++++ webhooks/functions/src/model/storage.test.ts | 4 ++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index f14f3882..441bbc47 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -89,11 +89,10 @@ app.middleware(async (conv: IConversationWithParams) => conv.session.params = {}; } + const bearerTokenRaw = conv.user.params.bearerToken; + const bearerToken = typeof bearerTokenRaw === "string" && bearerTokenRaw ? conv.user.params.bearerToken : BEARER_TOKEN_NOT_DEFINED; try { - const bearerToken = typeof conv.user.params.bearerToken === "string" ? conv.user.params.bearerToken : ""; - ok(bearerToken, "bearerToken not defined"); - const doc = await pull(bearerToken); const data = doc.exists ? doc.data() : undefined; const instance = StorageDto.create(data, bearerToken); @@ -103,7 +102,7 @@ app.middleware(async (conv: IConversationWithParams) => console.error('Middleware critical error firebase firestore'); console.error(e); - conv.user.params = StorageDto.create(undefined, BEARER_TOKEN_NOT_DEFINED); + conv.user.params = StorageDto.create(undefined, bearerToken); } console.log(conv.user.params); diff --git a/webhooks/functions/src/model/storage.dto.ts b/webhooks/functions/src/model/storage.dto.ts index de8f5a17..dc175d7d 100644 --- a/webhooks/functions/src/model/storage.dto.ts +++ b/webhooks/functions/src/model/storage.dto.ts @@ -2,6 +2,7 @@ import * as util from 'util'; import {IStorage, IStoragePlayer, IStoragePlayerCurrent, IStoragePlayerHistory, IStorageSelection} from './storage.interface'; import {classToPlain, Exclude, plainToClass, Transform, TransformationType, Type} from 'class-transformer'; import {Equals, IsBoolean, IsDate, IsNotEmpty, IsNumber, IsObject, IsOptional, IsString, IsUrl, Min, ValidateNested, validateSync} from 'class-validator'; +import { Timestamp } from "@google-cloud/firestore"; const DB_VERSION = 1; @@ -15,6 +16,15 @@ class StoragePlayerHistoryDto implements IStoragePlayerHistory { time: number; @IsDate() + @Transform(({value, type}) => { + if (type === TransformationType.PLAIN_TO_CLASS) { + if (value instanceof Timestamp) { + return value.toDate() + } else { + return value; + } + } + }) date: Date; // set(data: IStoragePlayerHistory) { diff --git a/webhooks/functions/src/model/storage.test.ts b/webhooks/functions/src/model/storage.test.ts index b79f51bc..c67f3344 100644 --- a/webhooks/functions/src/model/storage.test.ts +++ b/webhooks/functions/src/model/storage.test.ts @@ -2,6 +2,7 @@ import 'reflect-metadata'; import {StorageDto} from './storage.dto'; import * as assert from 'assert'; import {classToPlain} from 'class-transformer'; +import { inspect } from 'util'; describe('storage DTO', () => { @@ -228,6 +229,8 @@ describe('storage DTO', () => { selection: {}, }, extr); + console.log(inspect(extr, { depth: 7})); + console.log(new Date()); const instance2 = StorageDto.create(extr, 'test'); @@ -237,4 +240,5 @@ describe('storage DTO', () => { date: date, }); }); + }); From a5ef3da240680c9e8a06de69f8807429dcafcbf4 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 17 Nov 2021 18:30:50 +0100 Subject: [PATCH 029/180] fix: test and lint --- webhooks/functions/src/model/storage.dto.ts | 7 ++++--- webhooks/functions/src/model/storage.test.ts | 5 ++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/webhooks/functions/src/model/storage.dto.ts b/webhooks/functions/src/model/storage.dto.ts index dc175d7d..ed8e3110 100644 --- a/webhooks/functions/src/model/storage.dto.ts +++ b/webhooks/functions/src/model/storage.dto.ts @@ -2,7 +2,7 @@ import * as util from 'util'; import {IStorage, IStoragePlayer, IStoragePlayerCurrent, IStoragePlayerHistory, IStorageSelection} from './storage.interface'; import {classToPlain, Exclude, plainToClass, Transform, TransformationType, Type} from 'class-transformer'; import {Equals, IsBoolean, IsDate, IsNotEmpty, IsNumber, IsObject, IsOptional, IsString, IsUrl, Min, ValidateNested, validateSync} from 'class-validator'; -import { Timestamp } from "@google-cloud/firestore"; +import {Timestamp} from '@google-cloud/firestore'; const DB_VERSION = 1; @@ -19,11 +19,12 @@ class StoragePlayerHistoryDto implements IStoragePlayerHistory { @Transform(({value, type}) => { if (type === TransformationType.PLAIN_TO_CLASS) { if (value instanceof Timestamp) { - return value.toDate() + return value.toDate(); } else { - return value; + return new Date(value); } } + return value; }) date: Date; diff --git a/webhooks/functions/src/model/storage.test.ts b/webhooks/functions/src/model/storage.test.ts index c67f3344..427d36c0 100644 --- a/webhooks/functions/src/model/storage.test.ts +++ b/webhooks/functions/src/model/storage.test.ts @@ -2,7 +2,7 @@ import 'reflect-metadata'; import {StorageDto} from './storage.dto'; import * as assert from 'assert'; import {classToPlain} from 'class-transformer'; -import { inspect } from 'util'; +import {inspect} from 'util'; describe('storage DTO', () => { @@ -229,7 +229,7 @@ describe('storage DTO', () => { selection: {}, }, extr); - console.log(inspect(extr, { depth: 7})); + console.log(inspect(extr, {depth: 7})); console.log(new Date()); const instance2 = StorageDto.create(extr, 'test'); @@ -240,5 +240,4 @@ describe('storage DTO', () => { date: date, }); }); - }); From a60c820c7fdd22dcff54f18170a2f70abdfa40c8 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 18 Nov 2021 15:01:16 +0100 Subject: [PATCH 030/180] fix: firestore timestamp object conversion --- webhooks/functions/src/database/firestore.ts | 26 +++++++++++++++++--- webhooks/functions/src/index.ts | 8 ++++-- webhooks/functions/src/model/storage.dto.ts | 11 --------- webhooks/functions/src/model/storage.test.ts | 1 - 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/webhooks/functions/src/database/firestore.ts b/webhooks/functions/src/database/firestore.ts index dc40f446..c1681a2c 100644 --- a/webhooks/functions/src/database/firestore.ts +++ b/webhooks/functions/src/database/firestore.ts @@ -1,4 +1,5 @@ import * as admin from 'firebase-admin'; +import {Timestamp} from '@google-cloud/firestore'; admin.initializeApp(); @@ -9,9 +10,28 @@ export const push = async (key: string, value: FirebaseFirestore.DocumentData) = await docRef.set(value); }; -export const pull = async (key: string) => { + +// replace Timestamp object from firestore to Date native instance +// but why Firestore return a Timestamp object !? +const convertTimestampRecurs = (obj: {[str:string]:any}) => { + const ret = Object.entries(obj).reduce((pv, [k, v]) => { + return { + ...pv, + [k]: v instanceof Timestamp ? + v.toDate() : + typeof v === 'object' ? + convertTimestampRecurs(v) : + v, + }; + }, {}); + + return ret; +}; + +export const pull = async (key: string): Promise<{[str:string]:any}> => { const docRef = db.collection('user-storage').doc(key); const doc = await docRef.get(); - - return doc; + const data = doc.exists ? doc.data() : undefined; + const newData = data ? convertTimestampRecurs(data) : data; + return newData; }; diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 441bbc47..201a297b 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -93,11 +93,15 @@ app.middleware(async (conv: IConversationWithParams) => const bearerToken = typeof bearerTokenRaw === "string" && bearerTokenRaw ? conv.user.params.bearerToken : BEARER_TOKEN_NOT_DEFINED; try { - const doc = await pull(bearerToken); - const data = doc.exists ? doc.data() : undefined; + const data = await pull(bearerToken); + + // @ts-ignore + console.log(data.player.history); const instance = StorageDto.create(data, bearerToken); conv.user.params = instance; + + } catch (e) { console.error('Middleware critical error firebase firestore'); console.error(e); diff --git a/webhooks/functions/src/model/storage.dto.ts b/webhooks/functions/src/model/storage.dto.ts index ed8e3110..de8f5a17 100644 --- a/webhooks/functions/src/model/storage.dto.ts +++ b/webhooks/functions/src/model/storage.dto.ts @@ -2,7 +2,6 @@ import * as util from 'util'; import {IStorage, IStoragePlayer, IStoragePlayerCurrent, IStoragePlayerHistory, IStorageSelection} from './storage.interface'; import {classToPlain, Exclude, plainToClass, Transform, TransformationType, Type} from 'class-transformer'; import {Equals, IsBoolean, IsDate, IsNotEmpty, IsNumber, IsObject, IsOptional, IsString, IsUrl, Min, ValidateNested, validateSync} from 'class-validator'; -import {Timestamp} from '@google-cloud/firestore'; const DB_VERSION = 1; @@ -16,16 +15,6 @@ class StoragePlayerHistoryDto implements IStoragePlayerHistory { time: number; @IsDate() - @Transform(({value, type}) => { - if (type === TransformationType.PLAIN_TO_CLASS) { - if (value instanceof Timestamp) { - return value.toDate(); - } else { - return new Date(value); - } - } - return value; - }) date: Date; // set(data: IStoragePlayerHistory) { diff --git a/webhooks/functions/src/model/storage.test.ts b/webhooks/functions/src/model/storage.test.ts index 427d36c0..6db09b82 100644 --- a/webhooks/functions/src/model/storage.test.ts +++ b/webhooks/functions/src/model/storage.test.ts @@ -4,7 +4,6 @@ import * as assert from 'assert'; import {classToPlain} from 'class-transformer'; import {inspect} from 'util'; - describe('storage DTO', () => { it('create storage object', () => { const obj = { From c3bad9e957b5106f3b83ba8a755269d748bdea4a Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Fri, 19 Nov 2021 15:59:26 +0100 Subject: [PATCH 031/180] fix: test --- sdk/test/custom/intents/test_player_sdk.yaml | 3 +- sdk/test/custom/intents/test_setup_sdk.yaml | 1 + ...sk_to_resume_listening_at_last_offset.yaml | 2 +- sdk/test/push.sh | 1 - .../webhooks/ActionsOnGoogleFulfillment.yaml | 2 +- test/dev/test/test10.ts | 2 +- test/dev/test/test11.ts | 2 +- test/dev/test/test3.ts | 2 +- test/dev/test/test4.ts | 2 +- test/dev/test/test5.ts | 8 +- test/dev/test/test6.ts | 6 +- test/dev/test/test7.ts | 2 +- test/dev/test/test8.ts | 198 +----------------- test/dev/test/test9.ts | 148 ++----------- 14 files changed, 51 insertions(+), 328 deletions(-) delete mode 100644 sdk/test/push.sh diff --git a/sdk/test/custom/intents/test_player_sdk.yaml b/sdk/test/custom/intents/test_player_sdk.yaml index 6cb23dcc..69b07339 100644 --- a/sdk/test/custom/intents/test_player_sdk.yaml +++ b/sdk/test/custom/intents/test_player_sdk.yaml @@ -3,4 +3,5 @@ parameters: type: name: actions.type.Number trainingPhrases: -- test player sdk ($number '123' auto=true) +- test player sdk ($number '123' auto=false) +- test player ($number '123' auto=true) diff --git a/sdk/test/custom/intents/test_setup_sdk.yaml b/sdk/test/custom/intents/test_setup_sdk.yaml index 3efa6e61..dd25c1d1 100644 --- a/sdk/test/custom/intents/test_setup_sdk.yaml +++ b/sdk/test/custom/intents/test_setup_sdk.yaml @@ -3,5 +3,6 @@ parameters: type: name: actions.type.Number trainingPhrases: +- setup test ($number '123' auto=false) - test setup sdk ($number '123' auto=true) - setup test sdk ($number '123' auto=true) diff --git a/sdk/test/custom/scenes/ask_to_resume_listening_at_last_offset.yaml b/sdk/test/custom/scenes/ask_to_resume_listening_at_last_offset.yaml index f1a88cd8..84eb2ac0 100644 --- a/sdk/test/custom/scenes/ask_to_resume_listening_at_last_offset.yaml +++ b/sdk/test/custom/scenes/ask_to_resume_listening_at_last_offset.yaml @@ -3,7 +3,7 @@ intentEvents: webhookHandler: ask_to_resume_listening_at_last_offset__intent__yes intent: "yes" - handler: - webhookHandler: ask_to_resume_listening_at_last_offset__no + webhookHandler: ask_to_resume_listening_at_last_offset__intent__no intent: "no" onEnter: webhookHandler: ask_to_resume_listening_at_last_offset diff --git a/sdk/test/push.sh b/sdk/test/push.sh deleted file mode 100644 index 75909f98..00000000 --- a/sdk/test/push.sh +++ /dev/null @@ -1 +0,0 @@ -gactions push diff --git a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml index e602df67..03739391 100644 --- a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml @@ -3,7 +3,6 @@ handlers: - name: media_status - name: player - name: ask_to_resume_listening_at_last_offset -- name: ask_to_resume_listening_at_last_offset__no - name: main - name: home_lvl1 - name: home_lvl1__intent__enter_member_space_lvl1 @@ -35,6 +34,7 @@ handlers: - name: test_player_sdk - name: test_setup_sdk - name: test_webhook +- name: ask_to_resume_listening_at_last_offset__intent__no httpsEndpoint: baseUrl: https://us-central1-valentin-5.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/test/dev/test/test10.ts b/test/dev/test/test10.ts index 4c4eedcd..a14ced9e 100644 --- a/test/dev/test/test10.ts +++ b/test/dev/test/test10.ts @@ -6,7 +6,7 @@ import { inspect } from 'util'; import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; import * as chai from 'chai'; -const TEST_NUM = 9; +const TEST_NUM = 10; import * as fs from 'fs'; describe('My Action Test Suite', function () { diff --git a/test/dev/test/test11.ts b/test/dev/test/test11.ts index 8fed11f7..ad2ba9a6 100644 --- a/test/dev/test/test11.ts +++ b/test/dev/test/test11.ts @@ -6,7 +6,7 @@ import { inspect } from 'util'; import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; import * as chai from 'chai'; -const TEST_NUM = 9; +const TEST_NUM = 11; import * as fs from 'fs'; describe('My Action Test Suite', function () { diff --git a/test/dev/test/test3.ts b/test/dev/test/test3.ts index 33eba27e..d0592e76 100644 --- a/test/dev/test/test3.ts +++ b/test/dev/test/test3.ts @@ -55,7 +55,7 @@ describe('My Action Test Suite', function () { test.cleanUpAfterTest(); }); - it('search with bad query', async () => { + it('search with zola query', async () => { await startConversation(); await test.sendQuery("quitter"); // test.assertConversationEnded(); diff --git a/test/dev/test/test4.ts b/test/dev/test/test4.ts index c7980423..d40cf70a 100644 --- a/test/dev/test/test4.ts +++ b/test/dev/test/test4.ts @@ -250,7 +250,7 @@ describe('My Action Test Suite', function () { test.cleanUpAfterTest(); }); - it('search with bad query', async () => { + it('search with zola query bad number choice', async () => { await startConversation(); await test.sendQuery("quitter"); // test.assertConversationEnded(); diff --git a/test/dev/test/test5.ts b/test/dev/test/test5.ts index e5ee93bb..e2157e32 100644 --- a/test/dev/test/test5.ts +++ b/test/dev/test/test5.ts @@ -34,7 +34,13 @@ describe('My Action Test Suite', function () { test.assertSpeech(`Voulez-vous reprendre la lecture là où elle s'était arrêtée ?`); await test.sendQuery('oui'); + + // console.log(test.getLatestResponse()); + const media = test.getMedia(); + + // console.log(media); + chai.expect(media).to.deep.equal({ "optionalMediaControls": [ "PAUSED", @@ -207,7 +213,7 @@ describe('My Action Test Suite', function () { test.cleanUpAfterTest(); }); - it('search with bad query', async () => { + it('remaining playing', async () => { await startConversation(); await test.sendQuery("quitter"); // test.assertConversationEnded(); diff --git a/test/dev/test/test6.ts b/test/dev/test/test6.ts index 68455b5f..f7285132 100644 --- a/test/dev/test/test6.ts +++ b/test/dev/test/test6.ts @@ -32,9 +32,13 @@ describe('My Action Test Suite', function () { await test.sendQuery('lecture'); test.assertSpeech(`Voulez-vous reprendre la lecture là où elle s'était arrêtée ?`); + // console.log(test.getLatestResponse()); await test.sendQuery('non'); const media = test.getMedia(); + + // console.log(media); + // fs.writeFileSync('/tmp/media.json', JSON.stringify(media)); chai.expect(media).to.deep.equal({ "optionalMediaControls": [ @@ -236,7 +240,7 @@ describe('My Action Test Suite', function () { test.cleanUpAfterTest(); }); - it('search with bad query', async () => { + it('playing from beginning', async () => { await startConversation(); await test.sendQuery("quitter"); // test.assertConversationEnded(); diff --git a/test/dev/test/test7.ts b/test/dev/test/test7.ts index ba94d6b2..6d8825dd 100644 --- a/test/dev/test/test7.ts +++ b/test/dev/test/test7.ts @@ -246,7 +246,7 @@ describe('My Action Test Suite', function () { test.cleanUpAfterTest(); }); - it('search with bad query', async () => { + it('playing bad yes or no', async () => { await startConversation(); await test.sendQuery("quitter"); // test.assertConversationEnded(); diff --git a/test/dev/test/test8.ts b/test/dev/test/test8.ts index adba62e2..a2c27d76 100644 --- a/test/dev/test/test8.ts +++ b/test/dev/test/test8.ts @@ -35,7 +35,7 @@ describe('My Action Test Suite', function () { await test.sendQuery('non'); - let media = test.getMedia(); + const media = test.getMedia(); // fs.writeFileSync('/tmp/media.json', JSON.stringify(media)); chai.expect(media).to.deep.equal({ "optionalMediaControls": [ @@ -219,193 +219,17 @@ describe('My Action Test Suite', function () { "mediaType": "AUDIO" }); - await test.sendQuery('reprend la lecture'); + // await test.sendQuery('reprend la lecture'); - media = test.getMedia(); - // console.log(media); - // - // same - chai.expect(media).to.deep.equal({ - "optionalMediaControls": [ - "PAUSED", - "STOPPED" - ], - "mediaObjects": [ - { - "name": "Thérèse Raquin - 1", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap01-03.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 2", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap04-06.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 3", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap07-09.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 4", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap10-12.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 5", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap13-16.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 6", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap17-18.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 7", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap19-20.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 8", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap21-22.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 9", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap23-25.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 10", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap26-27.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 11", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap28-29.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 12", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap30-32.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - } - ], - "startOffset": { - "seconds": "0", - "nanos": 0 - }, - "mediaType": "AUDIO" - }); + // media = test.getMedia(); + // console.log(media); + + // // media === undefined + // // test doesn't handle intent during media playing + // // It's a TEST LIMITATION + // // + // // same + // chai.expect(media).to.equal(undefined); // diff --git a/test/dev/test/test9.ts b/test/dev/test/test9.ts index f6531f26..27169574 100644 --- a/test/dev/test/test9.ts +++ b/test/dev/test/test9.ts @@ -29,12 +29,12 @@ describe('My Action Test Suite', function () { test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre, Que voulez-vous faire ?`); await test.sendQuery(`ma liste`); - test.assertSpeech(`J’ai trouvé 2 publications. Pour choisir une publication dites son numéro:`); + test.assertSpeech(`Il y a 2 publications :\n Pour choisir une publication dite son numéronumero 1 : L'assommoir de Emile Zola\nnumero 2 : Du contrat social de Rousseau\n`); await test.sendQuery(`2`); const media = test.getMedia(); - // fs.writeFileSync('/tmp/media.json', JSON.stringify(media)); + // fs.writeFileSync('/tmp/media.json', JSON.stringify(media)); chai.expect(media).to.deep.equal({ "optionalMediaControls": [ "PAUSED", @@ -42,13 +42,13 @@ describe('My Action Test Suite', function () { ], "mediaObjects": [ { - "name": "Thérèse Raquin - 1", + "name": "Du contrat social - 1", "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap01-03.mp3", + "url": "https://archive.org/download/Du-contrat-social/Du_contrat_social_livre1.mp3", "image": { "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", + "url": "https://upload.wikimedia.org/wikipedia/commons/d/db/Social_contract_rousseau_page.jpg", + "alt": "Du contrat social", "height": 0, "width": 0 }, @@ -56,13 +56,13 @@ describe('My Action Test Suite', function () { } }, { - "name": "Thérèse Raquin - 2", + "name": "Du contrat social - 2", "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap04-06.mp3", + "url": "https://archive.org/download/Du-contrat-social/Du_contrat_social_livre2.mp3", "image": { "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", + "url": "https://upload.wikimedia.org/wikipedia/commons/d/db/Social_contract_rousseau_page.jpg", + "alt": "Du contrat social", "height": 0, "width": 0 }, @@ -70,13 +70,13 @@ describe('My Action Test Suite', function () { } }, { - "name": "Thérèse Raquin - 3", + "name": "Du contrat social - 3", "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap07-09.mp3", + "url": "https://archive.org/download/Du-contrat-social/Du_contrat_social_livre3.mp3", "image": { "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", + "url": "https://upload.wikimedia.org/wikipedia/commons/d/db/Social_contract_rousseau_page.jpg", + "alt": "Du contrat social", "height": 0, "width": 0 }, @@ -84,125 +84,13 @@ describe('My Action Test Suite', function () { } }, { - "name": "Thérèse Raquin - 4", + "name": "Du contrat social - 4", "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap10-12.mp3", + "url": "https://archive.org/download/Du-contrat-social/Du_contrat_social_livre4.mp3", "image": { "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 5", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap13-16.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 6", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap17-18.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 7", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap19-20.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 8", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap21-22.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 9", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap23-25.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 10", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap26-27.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 11", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap28-29.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 12", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap30-32.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", + "url": "https://upload.wikimedia.org/wikipedia/commons/d/db/Social_contract_rousseau_page.jpg", + "alt": "Du contrat social", "height": 0, "width": 0 }, From 3702730fca2f35117dccebcdd1b5d43dbd333954 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Fri, 19 Nov 2021 19:33:57 +0100 Subject: [PATCH 032/180] i18n | constant values (PR #10) --- webhooks/functions/src/constants.ts | 112 ++++++++++++++++++ webhooks/functions/src/conversation/test.ts | 4 +- webhooks/functions/src/index.ts | 99 ++++++++++------ webhooks/functions/src/service/listGroups.ts | 6 +- .../functions/src/service/listPublication.ts | 6 +- webhooks/functions/src/service/persist.ts | 4 +- .../functions/src/service/selectGroups.ts | 6 +- .../src/service/selectPublication.ts | 6 +- webhooks/functions/src/type.ts | 5 + 9 files changed, 193 insertions(+), 55 deletions(-) create mode 100644 webhooks/functions/src/constants.ts diff --git a/webhooks/functions/src/constants.ts b/webhooks/functions/src/constants.ts new file mode 100644 index 00000000..b0230dbc --- /dev/null +++ b/webhooks/functions/src/constants.ts @@ -0,0 +1,112 @@ + +export const SELECTION_URL = 'https://storage.googleapis.com/audiobook_edrlab/groups/popular.json'; +export const SEARCH_URL = 'https://europe-west1-audiobooks-a6348.cloudfunctions.net/indexer?url=https://storage.googleapis.com/audiobook_edrlab/navigation/all.json&query={query}'; +export const THEMATIC_LIST_URL = 'https://storage.googleapis.com/audiobook_edrlab/navigation/thematic_list.json'; +export const GENRE_LIST_URL = 'https://storage.googleapis.com/audiobook_edrlab/navigation/genre_list.json'; +export const DEFAULT_LANGUAGE: TLang = 'fr'; + +type TLang = 'fr' | 'en'; +type TI18nValue = (param: {[k: string]: any}) => string; +type TI18nItem = Required> & Partial>; + +export type TI18nKey = keyof typeof _i18n; + +const _i18n = { + 'error.bearerTokenNotDefined': { + 'fr': ({}) => `Aucun identifiant défini`, + 'en': ({}) => `bearerToken not defined`, + }, + 'error.catch': { + 'fr': ({}) => `une erreur s'est produite`, + 'en': ({}) => `an error happen`, + }, + 'error.convadd': { + 'fr': ({error}) => `conv.add value incorrect: ${error}`, + 'en': ({error}) => `conv.add value incorrect: ${error}`, + }, + 'main.welcome': { + 'fr': ({}) => `Bienvenue dans l\'application d\'écoute de livre audio valentin hauy`, + 'en': ({}) => `Bienvenue dans l\'application d\'écoute de livre audio valentin hauy`, + }, + 'home.welcome': { + 'fr': ({ }) => `Que voulez-vous faire ? Vous pouvez dire informations ou espace membres`, + 'en': ({}) => `Que voulez-vous faire ? Vous pouvez dire informations ou espace membres`, + }, + 'test.webhook': { + 'fr': ({message}) => `webhook works: ${message}`, + }, + 'home.information': { + 'fr': ({}) => `Voici les informations sur l\'association`, + }, + 'homeMembers.welcome.1': { + 'fr': ({}) => `Bienvenue dans l'espace membres. Les commandes possibles sont: sélection, lecture, recherche. `, + }, + 'homeMembers.welcome.2': { + 'fr': ({}) => `Que voulez-vous faire ?`, + }, + 'homeMembers.resumeAudiobook.noCurrentListening': { + 'fr': ({}) => `aucune lecture en cours`, + }, + 'homeMembers.selection.welcome': { + 'fr': ({}) => `Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre, Que voulez-vous faire ?`, + }, + 'homeMembers.selection.publication': { + 'fr': ({}) => `Pour choisir une publication dite son numéro`, + }, + 'homeMembers.selection.listAfterSelection': { + 'fr': ({}) => `Pour choisir une sélection dite son numéro`, + }, + 'error.selectionListNotDefined': { + 'fr': ({}) => `selection list url not defined`, + }, + 'error.selectionPubNotDefined': { + 'fr': ({}) => `selection url not defined`, + }, + 'error.selectionNotAvailable': { + 'fr': ({}) => `no selection url available`, + }, + 'ask_resume_last_offset': { + 'fr': ({}) => `Voulez-vous reprendre la lecture là où elle s\'était arrêtée ?`, + }, + 'error.urlNotValid': { + 'fr': ({}) => `url non définis ou invalide`, + }, + 'search': { + 'fr': ({}) => `Que voulez-vous écouter ? Par exemple Zola`, + }, + 'error.noQuery': { + 'fr': ({}) => `aucune requete demandée`, + }, + 'error.webpubNotDefined': { + 'fr': ({}) => `webpub non définis`, + }, + 'mediaStatus.notCorrect': { + 'fr': ({}) => `media status incorrect`, + }, + 'player.remaining.hoursAndMinute': { + 'fr': ({hours, minutes}) => `il reste ${hours} heures et ${minutes} minutes` + }, + 'player.remaining.minute': { + 'fr': ({minutes}) => `il reste ${minutes} minutes`, + }, + 'test.player': { + 'fr': ({nb}) => `test player ${nb}`, + }, + 'test.setupSdk': { + 'fr': ({nb}) => `setup test ${nb}`, + }, + 'noResult': { + 'fr': ({}) => `aucun résultat trouvé`, + }, + 'wrongNumber': { + 'fr': ({number}) => `Le numéro ${number} est inconnu. Veuillez choisir un autre numéro.` + }, + 'list.numberPublication': { + 'fr': ({length}) => `Il y a ${length} publications :\n`, + }, + 'free': { + 'fr': ({text}) => `${text}`, + } +} + +export const i18n: Record = _i18n; \ No newline at end of file diff --git a/webhooks/functions/src/conversation/test.ts b/webhooks/functions/src/conversation/test.ts index 10ba35bf..f880d758 100644 --- a/webhooks/functions/src/conversation/test.ts +++ b/webhooks/functions/src/conversation/test.ts @@ -30,7 +30,7 @@ export const testConversation = (app: TApp) => { console.log('test_PLAYER'); console.log(conv.user.params); - conv.add(`test player ${nb}`); + conv.add('test.player', {nb}); }); app.handle('test_setup_sdk', (conv) => { @@ -46,6 +46,6 @@ export const testConversation = (app: TApp) => { console.log('HELLLO '); - conv.add(`setup test ${nb}`); + conv.add('test.setupSdk', {nb}); }); }; diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 201a297b..74cd4c37 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -1,31 +1,29 @@ import {conversation, Media } from "@assistant/conversation"; import * as functions from "firebase-functions"; import {OpdsFetcher} from "opds-fetcher-parser"; -import {ok} from "assert"; +import {ok as _ok} from "assert"; // class-transformer import 'reflect-metadata'; import { pull, push } from "./database"; import { StorageDto } from "./model/storage.dto"; import { isValidHttpUrl } from "./utils"; -import { IConversationWithParams, MediaType, OptionalMediaControl } from "./type"; +import { IConversationWithParams, MediaType, OptionalMediaControl, TPromptItem } from "./type"; import { persistMediaPlayer } from "./service/persist"; import { listPublication } from "./service/listPublication"; import { selectPublication } from "./service/selectPublication"; import { testConversation } from "./conversation/test"; import { listGroups } from "./service/listGroups"; import { selectGroup } from "./service/selectGroups"; +import { DEFAULT_LANGUAGE, GENRE_LIST_URL, i18n, SEARCH_URL, SELECTION_URL, THEMATIC_LIST_URL, TI18nKey } from "./constants"; const BEARER_TOKEN_NOT_DEFINED = "bearer token not defined"; -const SELECTION_URL = 'https://storage.googleapis.com/audiobook_edrlab/groups/popular.json'; -const SEARCH_URL = 'https://europe-west1-audiobooks-a6348.cloudfunctions.net/indexer?url=https://storage.googleapis.com/audiobook_edrlab/navigation/all.json&query={query}'; -const THEMATIC_LIST_URL = 'https://storage.googleapis.com/audiobook_edrlab/navigation/thematic_list.json'; -const GENRE_LIST_URL = 'https://storage.googleapis.com/audiobook_edrlab/navigation/genre_list.json'; const app = conversation(); export type TApp = typeof app; const appHandle: typeof app.handle = app.handle.bind(app); +export const ok:(value: unknown, message?: TI18nKey) => asserts value = _ok.bind(_ok); app.handle = (path, fn) => { const ret = appHandle(path, async (conv) => { @@ -35,8 +33,8 @@ app.handle = (path, fn) => { const bearerToken = conv.user.params.bearerToken; try { - ok(bearerToken, "bearerToken not defined"); - ok(bearerToken !== BEARER_TOKEN_NOT_DEFINED, "bearerToken not defined") + ok(bearerToken, 'error.bearerTokenNotDefined'); + ok(bearerToken !== BEARER_TOKEN_NOT_DEFINED, 'error.bearerTokenNotDefined') const data = conv.user.params.extract(); await push(bearerToken, data); @@ -71,7 +69,7 @@ testConversation(app); // catch(catcher: ExceptionHandler): ConversationV3App // ExceptionHandler(conv: TConversation, error: Error): any app.catch((conv, error) => { - conv.add('une erreur s\'est produite'); + // conv.add('error.catch', { error: error.toString() }); console.log('ERROR'); console.log(error); @@ -92,7 +90,6 @@ app.middleware(async (conv: IConversationWithParams) => const bearerTokenRaw = conv.user.params.bearerToken; const bearerToken = typeof bearerTokenRaw === "string" && bearerTokenRaw ? conv.user.params.bearerToken : BEARER_TOKEN_NOT_DEFINED; try { - const data = await pull(bearerToken); // @ts-ignore @@ -100,8 +97,6 @@ app.middleware(async (conv: IConversationWithParams) => const instance = StorageDto.create(data, bearerToken); conv.user.params = instance; - - } catch (e) { console.error('Middleware critical error firebase firestore'); console.error(e); @@ -116,6 +111,30 @@ app.middleware(async (conv: IConversationWithParams) => ok(conv.user.params instanceof StorageDto); + console.log(conv.add); + + const convAdd: IConversationWithParams["add"] = conv.add.bind(conv); + conv.add = function (...promptItems) { + + const item: TPromptItem = promptItems[0] instanceof Media + ? promptItems[0] + : typeof promptItems[0] === "string" && i18n[promptItems[0]] && i18n[promptItems[0]][DEFAULT_LANGUAGE] + ? (i18n[promptItems[0]][(conv.user.locale || DEFAULT_LANGUAGE).split("-")[0]] || i18n[promptItems[0]][DEFAULT_LANGUAGE])(promptItems.length > 1 && typeof promptItems[1] === "object" ? promptItems[1] : {}) + : undefined; + + console.log(promptItems); + console.log(item); + + ok(item, 'error.convadd'); + + const ret = convAdd(item); + + return ret; + } + + console.log(conv.add); + console.log(convAdd); + // void }); @@ -132,21 +151,23 @@ app.handle('cancel', (conv) => { app.handle('main', (conv) => { - conv.add('Bienvenue dans l\'application d\'écoute de livre audio valentin hauy'); + console.log(conv.add); + + conv.add('main.welcome'); conv.scene.next.name = "home_members_lvl2"; }); app.handle('home_lvl1', (conv) => { - conv.add('Que voulez-vous faire ? Vous pouvez dire informations ou espace membres'); + conv.add('home.welcome'); // wait intent // conv.scene.next.name }); app.handle('test_webhook', (conv) => { - conv.add('Webook works :', functions.config().debug.message || ''); + conv.add('test.webhook', { message: functions.config().debug.message || '' }); console.log('TEST OK'); conv.scene.next.name = conv.scene.name; @@ -154,7 +175,7 @@ app.handle('test_webhook', (conv) => { app.handle('home_lvl1__intent__get_info_association_lvl1', (conv) => { - conv.add('Voici les informations sur l\'association'); + conv.add('home.information'); conv.scene.next.name = "home_lvl1"; }); @@ -176,8 +197,8 @@ app.handle('home_lvl1__intent__listen_audiobook_lvl1', (conv) => { app.handle('home_members_lvl2', (conv) => { - conv.add("Bienvenue dans l'espace membres. Les commandes possibles sont: sélection, lecture, recherche. "); - conv.add("Que voulez-vous faire ?"); + conv.add('homeMembers.welcome.1'); + conv.add('homeMembers.welcome.2'); }); app.handle('home_members_lvl2__intent__listen_audiobook_lvl2', (conv) => { @@ -199,7 +220,7 @@ app.handle('home_members_lvl2__intent__resume_audiobook_lvl2', (conv) => { const url = conv.user.params.player.current.url; if (!isValidHttpUrl(url)) { conv.scene.next.name = "home_members_lvl2"; - conv.add("aucune lecture en cours"); + conv.add('homeMembers.resumeAudiobook.noCurrentListening'); } else conv.scene.next.name = "ask_to_resume_listening_at_last_offset"; }); @@ -211,7 +232,7 @@ app.handle('home_members__intent__selection_audiobook_lvl2', (conv) => { app.handle('selection_lvl3', (conv) => { - conv.add("Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre, Que voulez-vous faire ?") + conv.add("homeMembers.selection.welcome"); // reset selection context conv.user.params.selection.url = undefined; @@ -256,14 +277,14 @@ app.handle('selection_lvl3__intent__selection_my_list_lvl3', async (conv) => { app.handle('select_pub_after_selection', (conv) => { - conv.add("Pour choisir une publication dite son numéro"); + conv.add('homeMembers.selection.publication'); // wait slot number or intent }); app.handle('select_list_after_list_selection', (conv) => { - conv.add("Pour choisir une sélection dite son numéro"); + conv.add('homeMembers.selection.listAfterSelection'); // wait slot number or intent }); @@ -275,12 +296,12 @@ app.handle('select_list_after_list_selection__slot__number', async (conv) => { const topUrl = conv.user.params.selection.topUrl; - ok(topUrl, "selection list url not defined"); + ok(topUrl, 'error.selectionListNotDefined'); await selectGroup(topUrl, number, conv); const url = conv.user.params.selection.url; - ok(url, 'selection url not defined'); + ok(url, 'error.selectionPubNotDefined'); await listPublication(url, conv, 'select_pub_after_selection'); console.log('select_publication_number END'); @@ -293,7 +314,7 @@ app.handle('select_pub_after_selection__slot__number', async (conv) => { const number = conv.intent.params?.number.resolved; const url = conv.user.params.selection.url; - ok(url, "no selection url available"); + ok(url, 'error.selectionNotAvailable'); await selectPublication(url, number, conv); console.log('select_publication_number END'); @@ -316,7 +337,7 @@ app.handle("ask_to_resume_listening_at_last_offset", async (conv) => { // const date = history.d; // TODO: use the date info - conv.add('Voulez-vous reprendre la lecture là où elle s\'était arrêtée ?'); + conv.add('ask_resume_last_offset'); // wait intent } else { @@ -334,7 +355,7 @@ app.handle('ask_to_resume_listening_at_last_offset__intent__yes', async (conv) = app.handle("ask_to_resume_listening_at_last_offset__intent__no", async (conv) => { const url = conv.user.params.player.current.url; - ok(isValidHttpUrl(url), "url not defined/valid " + url); + ok(isValidHttpUrl(url), 'error.urlNotValid'); console.log("erase ", url, " resume listening NO"); conv.user.params.player.current.index = 0; @@ -344,7 +365,7 @@ app.handle("ask_to_resume_listening_at_last_offset__intent__no", async (conv) => app.handle('search', (conv) => { - conv.add('Que voulez-vous écouter ? Par exemple Zola'); + conv.add('search'); // wait query intent }); @@ -355,7 +376,7 @@ app.handle('search__slot__query', async (conv) => { console.log('search_livre_lvl2 START'); const query = conv.intent.params?.query.resolved; - ok(typeof query === 'string', 'aucune requete demandée'); + ok(typeof query === 'string', 'error.noQuery'); conv.session.params.query = query; const url = SEARCH_URL.replace('{query}', encodeURIComponent(query)); @@ -374,7 +395,7 @@ app.handle('search__intent__resume_listening_player', (conv) => { app.handle('select_pub_after_search', (conv) => { - conv.add("Pour choisir une publication dite son numéro"); + conv.add('homeMembers.selection.publication'); // wait intent }); @@ -391,7 +412,7 @@ app.handle('select_pub_after_search__slot__number', async (conv) => { console.log('NUMBER: ', number); const query = conv.session.params.query; - ok(typeof query === 'string', 'aucune requete demandée'); + ok(typeof query === 'string', 'error.noQuery'); const url = SEARCH_URL.replace('{query}', encodeURIComponent(query)); console.log('select_pub_after_search__slot__number URL: ', url); @@ -403,7 +424,7 @@ app.handle('select_pub_after_search__slot__number', async (conv) => { app.handle("player", async (conv) => { const url = conv.user.params.player.current.url; - ok(isValidHttpUrl(url), "url not valid " + url); + ok(isValidHttpUrl(url), 'error.urlNotValid'); console.log("Player URL:", url); const startIndexRaw = conv.user.params.player.current.index; @@ -411,7 +432,7 @@ app.handle("player", async (conv) => { const opds = new OpdsFetcher(); const webpub = await opds.webpubRequest(url); - ok(webpub, 'webpub not defined'); + ok(webpub, 'error.webpubNotDefined'); const startIndex = (startIndexRaw && startIndexRaw <= webpub.readingOrders.length) ? startIndexRaw @@ -472,12 +493,12 @@ app.handle('player__intent__remaining_time_player', async (conv) => { persistMediaPlayer(conv); const url = conv.user.params?.player?.current?.url; - ok(url, "url not defined") - ok(isValidHttpUrl(url), "url not valid " + url); + ok(url, 'error.urlNotValid') + ok(isValidHttpUrl(url), 'error.urlNotValid'); const opds = new OpdsFetcher(); const webpub = await opds.webpubRequest(url); - ok(webpub, 'webpub not defined'); + ok(webpub, 'error.webpubNotDefined'); const index = conv.user.params.player.current.index || 0; const time = conv.user.params.player.current.time || 0; @@ -499,9 +520,9 @@ app.handle('player__intent__remaining_time_player', async (conv) => { const hours = Math.floor(minutes / 60); if (hours) { minutes = minutes % 60; - conv.add(`il reste ${hours} heures et ${minutes} minutes`); + conv.add('player.remaining.hoursAndMinute', { hours, minutes }); } else { - conv.add(`il reste ${minutes} minutes`); + conv.add('player.remaining.minute', { minutes }); } // // Acknowledge pause/stop @@ -541,7 +562,7 @@ app.handle('media_status', (conv) => { })); break; default: - conv.add('media status incorrect'); + conv.add('mediaStatus.notCorrect'); } console.log('MediaStatus END'); diff --git a/webhooks/functions/src/service/listGroups.ts b/webhooks/functions/src/service/listGroups.ts index dff57a2a..43073577 100644 --- a/webhooks/functions/src/service/listGroups.ts +++ b/webhooks/functions/src/service/listGroups.ts @@ -11,18 +11,18 @@ export async function listGroups(url: string, conv: IConversationWithParams, nex const length = list.length; if (length > 1) { conv.scene.next.name = nextScene; - conv.add(`Il y a ${length} sélections :\n`); + conv.add('list.numberPublication', {length}); let text = ''; list.map(({title}, i) => { text += `numero ${i + 1} : ${title}\n`; }); - conv.add(text); + conv.add('free', {text}); } else if (length === 1) { conv.scene.next.name = 'select_pub_after_selection'; conv.user.params.selection.url = list[0].groupUrl; } else { conv.scene.next.name = errorScene; - conv.add('aucun résultat trouvé'); + conv.add('noResult'); } } diff --git a/webhooks/functions/src/service/listPublication.ts b/webhooks/functions/src/service/listPublication.ts index 30fe7f32..9466de7d 100644 --- a/webhooks/functions/src/service/listPublication.ts +++ b/webhooks/functions/src/service/listPublication.ts @@ -11,18 +11,18 @@ export async function listPublication(url: string, conv: IConversationWithParams const length = list.length; if (length > 1) { conv.scene.next.name = nextScene; - conv.add(`Il y a ${length} publications :\n`); + conv.add('list.numberPublication', {length}); let text = ''; list.map(({title, author}, i) => { text += `numero ${i + 1} : ${title} ${author ? `de ${author}` : ''}\n`; }); - conv.add(text); + conv.add('free', {text}); } else if (length === 1) { conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; conv.user.params.player.current.url = list[0].webpuburl; } else { conv.scene.next.name = errorScene; - conv.add('aucun résultat trouvé'); + conv.add('noResult'); } } diff --git a/webhooks/functions/src/service/persist.ts b/webhooks/functions/src/service/persist.ts index 964c8e8b..ab3ec02c 100644 --- a/webhooks/functions/src/service/persist.ts +++ b/webhooks/functions/src/service/persist.ts @@ -1,6 +1,6 @@ import {isValidHttpUrl} from '../utils'; -import {ok} from 'assert'; import {IConversationWithParams} from '../type'; +import {ok} from '..'; export function persistMediaPlayer(conv: IConversationWithParams) { if (!conv.request.context) { @@ -14,7 +14,7 @@ export function persistMediaPlayer(conv: IConversationWithParams) { const progress = parseInt(_progress, 10); const index = conv.request.context?.media?.index || 0; const url = conv.user.params.player.current.url; - ok(isValidHttpUrl(url), 'url not defined/valid'); + ok(isValidHttpUrl(url), 'error.urlNotValid'); conv.user.params.player.current.index = index; conv.user.params.player.current.time = progress; diff --git a/webhooks/functions/src/service/selectGroups.ts b/webhooks/functions/src/service/selectGroups.ts index cb98ccd0..df659142 100644 --- a/webhooks/functions/src/service/selectGroups.ts +++ b/webhooks/functions/src/service/selectGroups.ts @@ -1,14 +1,14 @@ +import {ok} from '..'; import {IConversationWithParams} from '../type'; import {getGroupsFromFeed, isValidHttpUrl} from '../utils'; -import {ok} from 'assert'; export async function selectGroup(url: string, number: number, conv: IConversationWithParams) { - ok(isValidHttpUrl(url), 'url not valid'); + ok(isValidHttpUrl(url), 'error.urlNotValid'); const list = await getGroupsFromFeed(url); const group = list[number - 1]; if (!group) { console.log('NO GROUPS found !!'); - conv.add(`Le numéro ${number} est inconnu. Veuillez choisir un autre numéro.`); + conv.add('wrongNumber'); conv.scene.next.name = conv.scene.name; // loop selection or search return; diff --git a/webhooks/functions/src/service/selectPublication.ts b/webhooks/functions/src/service/selectPublication.ts index f0cc2686..6836305b 100644 --- a/webhooks/functions/src/service/selectPublication.ts +++ b/webhooks/functions/src/service/selectPublication.ts @@ -1,14 +1,14 @@ +import {ok} from '..'; import {IConversationWithParams} from '../type'; import {getPubsFromFeed, isValidHttpUrl} from '../utils'; -import {ok} from 'assert'; export async function selectPublication(url: string, number: number, conv: IConversationWithParams) { - ok(isValidHttpUrl(url), 'url not valid'); + ok(isValidHttpUrl(url), 'error.urlNotValid'); const list = await getPubsFromFeed(url); const pub = list[number - 1]; if (!pub) { console.log('NO PUBS found !!'); - conv.add(`Le numéro ${number} est inconnu. Veuillez choisir un autre numéro.`); + conv.add('wrongNumber'); conv.scene.next.name = conv.scene.name; // loop selection or search return; diff --git a/webhooks/functions/src/type.ts b/webhooks/functions/src/type.ts index d76e0c23..8157f117 100644 --- a/webhooks/functions/src/type.ts +++ b/webhooks/functions/src/type.ts @@ -1,5 +1,7 @@ import { ConversationV3 } from "@assistant/conversation"; +import { Media } from "@assistant/conversation/dist/api/schema"; import { User, Scene } from "@assistant/conversation/dist/conversation/handler"; +import { TI18nKey } from "./constants"; import { StorageDto } from "./model/storage.dto"; import { TSdkScene } from "./sdk"; @@ -15,6 +17,8 @@ export enum OptionalMediaControl { Stopped = 'STOPPED', } +export type TPromptItem = TI18nKey | {[k: string]: any} | Media; //PromtItem type from @assistant/conversation + interface IUser extends User { params: StorageDto; } @@ -27,6 +31,7 @@ interface IScene extends Scene { export interface IConversationWithParams extends ConversationV3 { user: IUser; scene: IScene; + add: (...promptItems: TPromptItem[]) => this; session: { params: { [key: string]: any; From 24825732807fb8c9a195a50eaa2fdbeca087a532 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 22 Nov 2021 15:45:57 +0100 Subject: [PATCH 033/180] fix: translation wrongNumber --- webhooks/functions/src/index.ts | 8 -------- webhooks/functions/src/service/selectGroups.ts | 2 +- webhooks/functions/src/service/selectPublication.ts | 2 +- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 74cd4c37..8293096a 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -111,8 +111,6 @@ app.middleware(async (conv: IConversationWithParams) => ok(conv.user.params instanceof StorageDto); - console.log(conv.add); - const convAdd: IConversationWithParams["add"] = conv.add.bind(conv); conv.add = function (...promptItems) { @@ -122,9 +120,6 @@ app.middleware(async (conv: IConversationWithParams) => ? (i18n[promptItems[0]][(conv.user.locale || DEFAULT_LANGUAGE).split("-")[0]] || i18n[promptItems[0]][DEFAULT_LANGUAGE])(promptItems.length > 1 && typeof promptItems[1] === "object" ? promptItems[1] : {}) : undefined; - console.log(promptItems); - console.log(item); - ok(item, 'error.convadd'); const ret = convAdd(item); @@ -132,9 +127,6 @@ app.middleware(async (conv: IConversationWithParams) => return ret; } - console.log(conv.add); - console.log(convAdd); - // void }); diff --git a/webhooks/functions/src/service/selectGroups.ts b/webhooks/functions/src/service/selectGroups.ts index df659142..55b64548 100644 --- a/webhooks/functions/src/service/selectGroups.ts +++ b/webhooks/functions/src/service/selectGroups.ts @@ -8,7 +8,7 @@ export async function selectGroup(url: string, number: number, conv: IConversati const group = list[number - 1]; if (!group) { console.log('NO GROUPS found !!'); - conv.add('wrongNumber'); + conv.add('wrongNumber', { number }); conv.scene.next.name = conv.scene.name; // loop selection or search return; diff --git a/webhooks/functions/src/service/selectPublication.ts b/webhooks/functions/src/service/selectPublication.ts index 6836305b..8dcc4e7c 100644 --- a/webhooks/functions/src/service/selectPublication.ts +++ b/webhooks/functions/src/service/selectPublication.ts @@ -8,7 +8,7 @@ export async function selectPublication(url: string, number: number, conv: IConv const pub = list[number - 1]; if (!pub) { console.log('NO PUBS found !!'); - conv.add('wrongNumber'); + conv.add('wrongNumber', { number }); conv.scene.next.name = conv.scene.name; // loop selection or search return; From 6045c404ce23c52582a2d274a9ed81aa75bb062f Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 22 Nov 2021 15:49:07 +0100 Subject: [PATCH 034/180] fix: lint --- webhooks/functions/src/service/selectGroups.ts | 2 +- webhooks/functions/src/service/selectPublication.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/webhooks/functions/src/service/selectGroups.ts b/webhooks/functions/src/service/selectGroups.ts index 55b64548..cbe2ca8c 100644 --- a/webhooks/functions/src/service/selectGroups.ts +++ b/webhooks/functions/src/service/selectGroups.ts @@ -8,7 +8,7 @@ export async function selectGroup(url: string, number: number, conv: IConversati const group = list[number - 1]; if (!group) { console.log('NO GROUPS found !!'); - conv.add('wrongNumber', { number }); + conv.add('wrongNumber', {number}); conv.scene.next.name = conv.scene.name; // loop selection or search return; diff --git a/webhooks/functions/src/service/selectPublication.ts b/webhooks/functions/src/service/selectPublication.ts index 8dcc4e7c..663c48f0 100644 --- a/webhooks/functions/src/service/selectPublication.ts +++ b/webhooks/functions/src/service/selectPublication.ts @@ -8,7 +8,7 @@ export async function selectPublication(url: string, number: number, conv: IConv const pub = list[number - 1]; if (!pub) { console.log('NO PUBS found !!'); - conv.add('wrongNumber', { number }); + conv.add('wrongNumber', {number}); conv.scene.next.name = conv.scene.name; // loop selection or search return; From 9613898f2e6583aaf382b99ffc0b96f2b837d3a6 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 22 Nov 2021 15:55:03 +0100 Subject: [PATCH 035/180] fix: github actions deploy and test jobs --- .github/workflows/functions-dev.yml | 25 +++++++++++++++++++++++++ .github/workflows/sdk-test-dev.yml | 5 ++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/.github/workflows/functions-dev.yml b/.github/workflows/functions-dev.yml index 123f1056..24c05aef 100644 --- a/.github/workflows/functions-dev.yml +++ b/.github/workflows/functions-dev.yml @@ -69,3 +69,28 @@ jobs: env: FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} PROJECT_PATH: './webhooks' + + sdk-test-dev: + name: "Test sdk DEV" + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [14.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + defaults: + run: + working-directory: './test/dev' + + steps: + + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node }} + + - name: save service_account + run: echo $SECRET >> service_account.json + env: + SECRET : ${{ secrets.SERVICE_ACCOUNT_VALENTIN5 }} + - run: npm install + - run: npm test \ No newline at end of file diff --git a/.github/workflows/sdk-test-dev.yml b/.github/workflows/sdk-test-dev.yml index bad835c5..8c2c9fae 100644 --- a/.github/workflows/sdk-test-dev.yml +++ b/.github/workflows/sdk-test-dev.yml @@ -7,9 +7,12 @@ on: # paths: # pull_request: # branches: [ develop ] + paths: + - 'sdk/test/**' + - '.github/workflows/sdk-test-dev.yml' jobs: - sdk-test-prod: + sdk-test-dev: name: "Test sdk DEV" runs-on: ubuntu-latest strategy: From 95fcdb39464c789b31cd01fcd5a5b56f722598da Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 22 Nov 2021 16:01:04 +0100 Subject: [PATCH 036/180] fix: github actions deploy --- .github/workflows/functions-dev.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/functions-dev.yml b/.github/workflows/functions-dev.yml index 24c05aef..f0607a50 100644 --- a/.github/workflows/functions-dev.yml +++ b/.github/workflows/functions-dev.yml @@ -72,6 +72,7 @@ jobs: sdk-test-dev: name: "Test sdk DEV" + needs: deploy runs-on: ubuntu-latest strategy: matrix: From 2a0b24eb360a58547107c76c2a40fb86bcea8e42 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 22 Nov 2021 16:25:49 +0100 Subject: [PATCH 037/180] feature: stop in selections --- sdk/test/custom/intents/stop.yaml | 4 ++ .../scenes/select_pub_after_search.yaml | 3 + .../scenes/select_pub_after_selection.yaml | 3 + .../webhooks/ActionsOnGoogleFulfillment.yaml | 2 + test/dev/test/test12.ts | 67 +++++++++++++++++++ test/dev/test/test13.ts | 60 +++++++++++++++++ webhooks/functions/src/index.ts | 10 +++ 7 files changed, 149 insertions(+) create mode 100644 sdk/test/custom/intents/stop.yaml create mode 100644 test/dev/test/test12.ts create mode 100644 test/dev/test/test13.ts diff --git a/sdk/test/custom/intents/stop.yaml b/sdk/test/custom/intents/stop.yaml new file mode 100644 index 00000000..112ca5de --- /dev/null +++ b/sdk/test/custom/intents/stop.yaml @@ -0,0 +1,4 @@ +trainingPhrases: +- revenir au menu précédent +- partir +- stop diff --git a/sdk/test/custom/scenes/select_pub_after_search.yaml b/sdk/test/custom/scenes/select_pub_after_search.yaml index 4302dc5f..b29c202c 100644 --- a/sdk/test/custom/scenes/select_pub_after_search.yaml +++ b/sdk/test/custom/scenes/select_pub_after_search.yaml @@ -2,6 +2,9 @@ intentEvents: - handler: webhookHandler: select_pub_after_search__intent__resume_listening_player intent: resume_listening_player +- handler: + webhookHandler: select_pub_after_search__intent__stop + intent: stop - handler: staticPrompt: candidates: diff --git a/sdk/test/custom/scenes/select_pub_after_selection.yaml b/sdk/test/custom/scenes/select_pub_after_selection.yaml index 0c2c44cc..520e74d4 100644 --- a/sdk/test/custom/scenes/select_pub_after_selection.yaml +++ b/sdk/test/custom/scenes/select_pub_after_selection.yaml @@ -2,6 +2,9 @@ intentEvents: - handler: webhookHandler: select_pub_after_selection__intent__resume_listening_player intent: resume_listening_player +- handler: + webhookHandler: select_pub_after_selection__intent__stop + intent: stop - handler: staticPrompt: candidates: diff --git a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml index 03739391..f2f5bcdb 100644 --- a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml @@ -35,6 +35,8 @@ handlers: - name: test_setup_sdk - name: test_webhook - name: ask_to_resume_listening_at_last_offset__intent__no +- name: select_pub_after_search__intent__stop +- name: select_pub_after_selection__intent__stop httpsEndpoint: baseUrl: https://us-central1-valentin-5.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/test/dev/test/test12.ts b/test/dev/test/test12.ts new file mode 100644 index 00000000..111c2299 --- /dev/null +++ b/test/dev/test/test12.ts @@ -0,0 +1,67 @@ +import 'mocha'; + +import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; +import {ok} from 'assert'; +import { inspect } from 'util'; +import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; +import * as fs from 'fs'; +import * as chai from 'chai'; + +const TEST_NUM = 12; + +describe('My Action Test Suite', function () { + // Set the timeout for each test run to 60s. + this.timeout(60000); + let test: ActionsOnGoogleTestManager; + + async function startConversation() { + await test.sendQuery(TRIGGER_PHRASE); + test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); + // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertIntent('actions.intent.MAIN'); + test.assertScene('home_members_lvl2'); + + await test.sendQuery(`setup test ${TEST_NUM}`); + + test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); + + // RECHERCHE + + await test.sendQuery('recherche'); + + test.assertSpeech(`Que voulez-vous écouter ?`); + + await test.sendQuery('zola'); + + await test.assertSpeech(`Il y a 2 publications :\n Pour choisir une publication dite son numéronumero 1 : Thérèse Raquin de Emile Zola\nnumero 2 : L'assommoir de Emile Zola\n`); + + await test.sendQuery('0'); + + await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. Pour choisir une publication dite son numéro`); + + test.assertScene('select_pub_after_search'); + + await test.sendQuery('stop'); + + test.assertSpeech(MEMBER_PROMPT); + + } + + before('before all', async () => { + // Load project settings to read project ID and trigger phrase. + test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); + await test.writePreviewFromDraft(); + test.setSuiteLocale(DEFAULT_LOCALE); + test.setSuiteSurface(DEFAULT_SURFACE); + }); + + afterEach('post test cleans', async () => { + test.cleanUpAfterTest(); + }); + + it('search with zola query bad number choice and then stop it', async () => { + await startConversation(); + await test.sendQuery("quitter"); + // test.assertConversationEnded(); + }); +}); diff --git a/test/dev/test/test13.ts b/test/dev/test/test13.ts new file mode 100644 index 00000000..52d900f0 --- /dev/null +++ b/test/dev/test/test13.ts @@ -0,0 +1,60 @@ +import 'mocha'; + +import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; +import {ok} from 'assert'; +import { inspect } from 'util'; +import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; +import * as chai from 'chai'; + +const TEST_NUM = 13; +import * as fs from 'fs'; + +describe('My Action Test Suite', function () { + // Set the timeout for each test run to 60s. + this.timeout(60000); + let test: ActionsOnGoogleTestManager; + + async function startConversation() { + await test.sendQuery(TRIGGER_PHRASE); + test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); + // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertIntent('actions.intent.MAIN'); + test.assertScene('home_members_lvl2'); + + await test.sendQuery(`setup test ${TEST_NUM}`); + test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); + + + await test.sendQuery(`sélections`); + test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre, Que voulez-vous faire ?`); + + await test.sendQuery(`selections par genre`); + + test.assertSpeech(``); + + await test.sendQuery(`revenir au menu principal`); + + test.assertSpeech(MEMBER_PROMPT); + + // + // resp = test.getLatestResponse(); + } + + before('before all', async () => { + // Load project settings to read project ID and trigger phrase. + test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); + await test.writePreviewFromDraft(); + test.setSuiteLocale(DEFAULT_LOCALE); + test.setSuiteSurface(DEFAULT_SURFACE); + }); + + afterEach('post test cleans', async () => { + test.cleanUpAfterTest(); + }); + + it('genre selection then stop', async () => { + await startConversation(); + await test.sendQuery("quitter"); + // test.assertConversationEnded(); + }); +}); diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 8293096a..81898af2 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -312,6 +312,11 @@ app.handle('select_pub_after_selection__slot__number', async (conv) => { console.log('select_publication_number END'); }); +app.handle('select_pub_after_selection__intent__stop', (conv) => { + + conv.scene.next.name = 'home_members_lvl2'; +}); + app.handle('select_pub_after_selection__intent__resume_listening_player', (conv) => { conv.scene.next.name = "select_pub_after_selection"; @@ -392,6 +397,11 @@ app.handle('select_pub_after_search', (conv) => { // wait intent }); +app.handle('select_pub_after_search__intent__stop', (conv) => { + + conv.scene.next.name = 'home_members_lvl2'; +}); + app.handle('select_pub_after_search__intent__resume_listening_player', (conv) => { conv.scene.next.name = "select_pub_after_search"; From 6d00c719967c35c7412d745c66912824f0dd971d Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 22 Nov 2021 16:54:21 +0100 Subject: [PATCH 038/180] fix: stop in selection_list --- sdk/test/custom/intents/stop.yaml | 3 +-- sdk/test/custom/scenes/select_list_after_list_selection.yaml | 3 +++ sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml | 1 + test/dev/test/test12.ts | 2 +- webhooks/functions/src/index.ts | 5 +++++ 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/sdk/test/custom/intents/stop.yaml b/sdk/test/custom/intents/stop.yaml index 112ca5de..432c35ff 100644 --- a/sdk/test/custom/intents/stop.yaml +++ b/sdk/test/custom/intents/stop.yaml @@ -1,4 +1,3 @@ trainingPhrases: - revenir au menu précédent -- partir -- stop +- partir de là diff --git a/sdk/test/custom/scenes/select_list_after_list_selection.yaml b/sdk/test/custom/scenes/select_list_after_list_selection.yaml index 6bbfee5c..dae8d20c 100644 --- a/sdk/test/custom/scenes/select_list_after_list_selection.yaml +++ b/sdk/test/custom/scenes/select_list_after_list_selection.yaml @@ -1,4 +1,7 @@ intentEvents: +- handler: + webhookHandler: select_list_after_list_selection__intent__stop + intent: stop - handler: staticPrompt: candidates: diff --git a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml index f2f5bcdb..fec8a8f3 100644 --- a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml @@ -37,6 +37,7 @@ handlers: - name: ask_to_resume_listening_at_last_offset__intent__no - name: select_pub_after_search__intent__stop - name: select_pub_after_selection__intent__stop +- name: select_list_after_list_selection__intent__stop httpsEndpoint: baseUrl: https://us-central1-valentin-5.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/test/dev/test/test12.ts b/test/dev/test/test12.ts index 111c2299..45fe7753 100644 --- a/test/dev/test/test12.ts +++ b/test/dev/test/test12.ts @@ -41,7 +41,7 @@ describe('My Action Test Suite', function () { test.assertScene('select_pub_after_search'); - await test.sendQuery('stop'); + await test.sendQuery('revenir au menu principal'); test.assertSpeech(MEMBER_PROMPT); diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 81898af2..9b3f5fda 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -281,6 +281,11 @@ app.handle('select_list_after_list_selection', (conv) => { // wait slot number or intent }); +app.handle('select_list_after_list_selection__intent__stop', (conv) => { + + conv.scene.next.name = 'home_members_lvl2'; +}); + app.handle('select_list_after_list_selection__slot__number', async (conv) => { console.log('select_publication_number START'); From 2df1ae0cdaccb574edbcdc8c29afbc827f99dc69 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 25 Nov 2021 18:30:02 +0100 Subject: [PATCH 039/180] I18n (PR #12) --- webhooks/functions/package-lock.json | 359 +++++++++++++++++- webhooks/functions/package.json | 14 +- webhooks/functions/src/constants.ts | 106 +----- webhooks/functions/src/index.ts | 32 +- webhooks/functions/src/service/listGroups.ts | 7 +- .../functions/src/service/listPublication.ts | 8 +- .../functions/src/service/selectGroups.ts | 2 +- .../src/service/selectPublication.ts | 2 +- webhooks/functions/src/translation/fr/fr.json | 56 +++ webhooks/functions/src/translation/index.ts | 21 + webhooks/functions/src/type.ts | 2 +- webhooks/functions/src/typings/i18n.d.ts | 11 + webhooks/functions/tsconfig.json | 3 +- 13 files changed, 488 insertions(+), 135 deletions(-) create mode 100644 webhooks/functions/src/translation/fr/fr.json create mode 100644 webhooks/functions/src/translation/index.ts create mode 100644 webhooks/functions/src/typings/i18n.d.ts diff --git a/webhooks/functions/package-lock.json b/webhooks/functions/package-lock.json index 52603dac..dcf0bcf9 100644 --- a/webhooks/functions/package-lock.json +++ b/webhooks/functions/package-lock.json @@ -47,6 +47,14 @@ } } }, + "@babel/runtime": { + "version": "7.16.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz", + "integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, "@cspotcode/source-map-consumer": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", @@ -62,6 +70,16 @@ "@cspotcode/source-map-consumer": "0.8.0" } }, + "@dsherret/to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@dsherret/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha1-H2R13IvZdM6gei2vOGSzF7HdMyw=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + } + }, "@eslint/eslintrc": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.4.tgz", @@ -487,6 +505,25 @@ "@types/express": "*" } }, + "@types/fs-extra": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz", + "integrity": "sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, "@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", @@ -510,6 +547,12 @@ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, + "@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, "@types/mocha": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.0.0.tgz", @@ -756,6 +799,12 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "array-differ": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", + "dev": true + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -1022,6 +1071,12 @@ "wrap-ansi": "^7.0.0" } }, + "code-block-writer": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-10.1.1.tgz", + "integrity": "sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==", + "dev": true + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1043,6 +1098,12 @@ "delayed-stream": "~1.0.0" } }, + "commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "dev": true + }, "compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -1875,6 +1936,17 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1896,6 +1968,16 @@ "inherits": "~2.0.0", "mkdirp": ">=0.5 0", "rimraf": "2" + }, + "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + } } }, "functional-red-black-tree": { @@ -2156,6 +2238,14 @@ "debug": "4" } }, + "i18next": { + "version": "21.5.3", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.5.3.tgz", + "integrity": "sha512-9R8127a0/N5okiD7eeo6XBPQsHgHsLr1GdQEa35Pcw305ArC9KZDLs9kbgdn3xuVUNYlVu8+gWzz73eVkna0gA==", + "requires": { + "@babel/runtime": "^7.12.0" + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -2212,6 +2302,16 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -2241,6 +2341,12 @@ "is-extglob": "^2.1.1" } }, + "is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", + "dev": true + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -2259,6 +2365,15 @@ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "requires": { + "is-unc-path": "^1.0.0" + } + }, "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -2275,12 +2390,27 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.2" + } + }, "is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -2348,6 +2478,15 @@ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, "jsonwebtoken": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", @@ -2534,6 +2673,18 @@ "is-unicode-supported": "^0.1.0" } }, + "loglevel": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz", + "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==", + "dev": true + }, + "loglevel-plugin-prefix": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", + "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", + "dev": true + }, "long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", @@ -2744,6 +2895,19 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "multimatch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz", + "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==", + "dev": true, + "requires": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + } + }, "nanoid": { "version": "3.1.30", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz", @@ -3163,6 +3327,11 @@ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" }, + "regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, "regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -3260,9 +3429,10 @@ "dev": true }, "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, "requires": { "glob": "^7.1.3" } @@ -3582,6 +3752,103 @@ } } }, + "ts-morph": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-4.3.3.tgz", + "integrity": "sha512-yauxRJM4Vo+KvpJFgL4Mp9PtFjwZVrt54eP3RkLIXnaaAY5TGVHTLqN2OnLGwf6YjyqkDLAKprZVOUTvVEz6ZQ==", + "dev": true, + "requires": { + "@dsherret/to-absolute-glob": "^2.0.2", + "chalk": "^2.4.2", + "code-block-writer": "^10.0.0", + "fs-extra": "^8.1.0", + "glob-parent": "^5.1.0", + "globby": "^10.0.1", + "is-negated-glob": "^1.0.0", + "multimatch": "^4.0.0", + "typescript": "3.0.1 - 3.6.4" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "typescript": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz", + "integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==", + "dev": true + } + } + }, "ts-node": { "version": "10.4.0", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", @@ -3669,6 +3936,80 @@ "mime-types": "~2.1.24" } }, + "typed-i18next": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/typed-i18next/-/typed-i18next-0.1.2.tgz", + "integrity": "sha512-3Zn04Enaz55WSLKKxj31+pYSvWicYpFAMdIClcErtxLdwU6p1aZ9QU9vhMwYE0qrXSxBTIvViZSy5J54arhJqQ==", + "dev": true, + "requires": { + "@types/fs-extra": "^8.0.0", + "chalk": "^2.4.2", + "commander": "^3.0.2", + "fs-extra": "^8.1.0", + "loglevel": "^1.6.4", + "loglevel-plugin-prefix": "^0.8.4", + "ts-morph": "^4.2.0", + "upath": "^1.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -3690,6 +4031,12 @@ "integrity": "sha512-1hNKM37dAWML/2ltRXupOq2uqcdRQyDFphl+341NTPXFLLLiDhErXx8VtaSLh3xP7SyHZdcCgpt9boYYVb3fQg==", "dev": true }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, "unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", @@ -3768,6 +4115,12 @@ } } }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index 13be34bb..27772845 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -10,7 +10,8 @@ "build": "tsc", "test": "mocha --recursive --require ts-node/register src/**/*.test.ts", "lint": "eslint src/**/*.ts", - "typed:scene": "echo \"// npm run typed:scene \n\n\nexport type TSdkScene = \" $(for I in `ls ../../sdk/test/custom/scenes | cut -d \".\" -f1`; do echo \"'$I' |\"; done) | sed 's/..$/;/' > src/sdk.d.ts" + "scene-typed": "echo \"// npm run scene-typed \n\n\nexport type TSdkScene = \" $(for I in `ls ../../sdk/test/custom/scenes | cut -d \".\" -f1`; do echo \"'$I' |\"; done) | sed 's/..$/;/' > src/sdk.d.ts", + "i18n-typed": "typed-i18next -i src/translation -o src/typings/i18n.d.ts" }, "engines": { "node": "14" @@ -22,19 +23,22 @@ "class-validator": "^0.13.1", "firebase-admin": "^9.8.0", "firebase-functions": "^3.16.0", + "i18next": "^21.5.3", "opds-fetcher-parser": "github:panaC/opds_fetcher_parser#46f59a92513c17a060d02dfceb82633bbbbc4be3", "reflect-metadata": "^0.1.13" }, "devDependencies": { "@types/mocha": "^9.0.0", - "firebase-functions-test": "^0.2.0", - "mocha": "^9.1.3", - "ts-node": "^10.4.0", - "typescript": "^4.4.4", "@typescript-eslint/eslint-plugin": "^5.3.1", "@typescript-eslint/parser": "^5.3.1", "eslint": "^8.2.0", "eslint-config-google": "^0.14.0", + "firebase-functions-test": "^0.2.0", + "mocha": "^9.1.3", + "rimraf": "^3.0.2", + "ts-node": "^10.4.0", + "typed-i18next": "^0.1.2", + "typescript": "^4.4.4", "typescript-eslint": "0.0.1-alpha.0" }, "private": true diff --git a/webhooks/functions/src/constants.ts b/webhooks/functions/src/constants.ts index b0230dbc..95668b4e 100644 --- a/webhooks/functions/src/constants.ts +++ b/webhooks/functions/src/constants.ts @@ -5,108 +5,4 @@ export const THEMATIC_LIST_URL = 'https://storage.googleapis.com/audiobook_edrla export const GENRE_LIST_URL = 'https://storage.googleapis.com/audiobook_edrlab/navigation/genre_list.json'; export const DEFAULT_LANGUAGE: TLang = 'fr'; -type TLang = 'fr' | 'en'; -type TI18nValue = (param: {[k: string]: any}) => string; -type TI18nItem = Required> & Partial>; - -export type TI18nKey = keyof typeof _i18n; - -const _i18n = { - 'error.bearerTokenNotDefined': { - 'fr': ({}) => `Aucun identifiant défini`, - 'en': ({}) => `bearerToken not defined`, - }, - 'error.catch': { - 'fr': ({}) => `une erreur s'est produite`, - 'en': ({}) => `an error happen`, - }, - 'error.convadd': { - 'fr': ({error}) => `conv.add value incorrect: ${error}`, - 'en': ({error}) => `conv.add value incorrect: ${error}`, - }, - 'main.welcome': { - 'fr': ({}) => `Bienvenue dans l\'application d\'écoute de livre audio valentin hauy`, - 'en': ({}) => `Bienvenue dans l\'application d\'écoute de livre audio valentin hauy`, - }, - 'home.welcome': { - 'fr': ({ }) => `Que voulez-vous faire ? Vous pouvez dire informations ou espace membres`, - 'en': ({}) => `Que voulez-vous faire ? Vous pouvez dire informations ou espace membres`, - }, - 'test.webhook': { - 'fr': ({message}) => `webhook works: ${message}`, - }, - 'home.information': { - 'fr': ({}) => `Voici les informations sur l\'association`, - }, - 'homeMembers.welcome.1': { - 'fr': ({}) => `Bienvenue dans l'espace membres. Les commandes possibles sont: sélection, lecture, recherche. `, - }, - 'homeMembers.welcome.2': { - 'fr': ({}) => `Que voulez-vous faire ?`, - }, - 'homeMembers.resumeAudiobook.noCurrentListening': { - 'fr': ({}) => `aucune lecture en cours`, - }, - 'homeMembers.selection.welcome': { - 'fr': ({}) => `Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre, Que voulez-vous faire ?`, - }, - 'homeMembers.selection.publication': { - 'fr': ({}) => `Pour choisir une publication dite son numéro`, - }, - 'homeMembers.selection.listAfterSelection': { - 'fr': ({}) => `Pour choisir une sélection dite son numéro`, - }, - 'error.selectionListNotDefined': { - 'fr': ({}) => `selection list url not defined`, - }, - 'error.selectionPubNotDefined': { - 'fr': ({}) => `selection url not defined`, - }, - 'error.selectionNotAvailable': { - 'fr': ({}) => `no selection url available`, - }, - 'ask_resume_last_offset': { - 'fr': ({}) => `Voulez-vous reprendre la lecture là où elle s\'était arrêtée ?`, - }, - 'error.urlNotValid': { - 'fr': ({}) => `url non définis ou invalide`, - }, - 'search': { - 'fr': ({}) => `Que voulez-vous écouter ? Par exemple Zola`, - }, - 'error.noQuery': { - 'fr': ({}) => `aucune requete demandée`, - }, - 'error.webpubNotDefined': { - 'fr': ({}) => `webpub non définis`, - }, - 'mediaStatus.notCorrect': { - 'fr': ({}) => `media status incorrect`, - }, - 'player.remaining.hoursAndMinute': { - 'fr': ({hours, minutes}) => `il reste ${hours} heures et ${minutes} minutes` - }, - 'player.remaining.minute': { - 'fr': ({minutes}) => `il reste ${minutes} minutes`, - }, - 'test.player': { - 'fr': ({nb}) => `test player ${nb}`, - }, - 'test.setupSdk': { - 'fr': ({nb}) => `setup test ${nb}`, - }, - 'noResult': { - 'fr': ({}) => `aucun résultat trouvé`, - }, - 'wrongNumber': { - 'fr': ({number}) => `Le numéro ${number} est inconnu. Veuillez choisir un autre numéro.` - }, - 'list.numberPublication': { - 'fr': ({length}) => `Il y a ${length} publications :\n`, - }, - 'free': { - 'fr': ({text}) => `${text}`, - } -} - -export const i18n: Record = _i18n; \ No newline at end of file +type TLang = 'fr' | 'en'; \ No newline at end of file diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 9b3f5fda..7b00b64b 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -15,7 +15,8 @@ import { selectPublication } from "./service/selectPublication"; import { testConversation } from "./conversation/test"; import { listGroups } from "./service/listGroups"; import { selectGroup } from "./service/selectGroups"; -import { DEFAULT_LANGUAGE, GENRE_LIST_URL, i18n, SEARCH_URL, SELECTION_URL, THEMATIC_LIST_URL, TI18nKey } from "./constants"; +import { GENRE_LIST_URL, SEARCH_URL, SELECTION_URL, THEMATIC_LIST_URL } from "./constants"; +import { i18n, t, TI18nKey } from "./translation"; const BEARER_TOKEN_NOT_DEFINED = "bearer token not defined"; @@ -23,7 +24,11 @@ const app = conversation(); export type TApp = typeof app; const appHandle: typeof app.handle = app.handle.bind(app); -export const ok:(value: unknown, message?: TI18nKey) => asserts value = _ok.bind(_ok); +const __ok:(value: unknown, message?: TI18nKey) => asserts value = _ok.bind(_ok); +export const ok: typeof __ok = (v, m) => { + return __ok(v, m ? t(m): undefined); +} + app.handle = (path, fn) => { const ret = appHandle(path, async (conv) => { @@ -87,6 +92,9 @@ app.middleware(async (conv: IConversationWithParams) => conv.session.params = {}; } + const locale = conv.user.locale; + await i18n.changeLanguage(locale); + const bearerTokenRaw = conv.user.params.bearerToken; const bearerToken = typeof bearerTokenRaw === "string" && bearerTokenRaw ? conv.user.params.bearerToken : BEARER_TOKEN_NOT_DEFINED; try { @@ -114,10 +122,10 @@ app.middleware(async (conv: IConversationWithParams) => const convAdd: IConversationWithParams["add"] = conv.add.bind(conv); conv.add = function (...promptItems) { - const item: TPromptItem = promptItems[0] instanceof Media + const item: TPromptItem | undefined = promptItems[0] instanceof Media ? promptItems[0] - : typeof promptItems[0] === "string" && i18n[promptItems[0]] && i18n[promptItems[0]][DEFAULT_LANGUAGE] - ? (i18n[promptItems[0]][(conv.user.locale || DEFAULT_LANGUAGE).split("-")[0]] || i18n[promptItems[0]][DEFAULT_LANGUAGE])(promptItems.length > 1 && typeof promptItems[1] === "object" ? promptItems[1] : {}) + : typeof promptItems[0] === "string" + ? t(promptItems[0], typeof promptItems[1] === "object" ? promptItems[1] : undefined) : undefined; ok(item, 'error.convadd'); @@ -152,7 +160,7 @@ app.handle('main', (conv) => { app.handle('home_lvl1', (conv) => { - conv.add('home.welcome'); + conv.add('main.welcome'); // wait intent // conv.scene.next.name @@ -189,8 +197,8 @@ app.handle('home_lvl1__intent__listen_audiobook_lvl1', (conv) => { app.handle('home_members_lvl2', (conv) => { - conv.add('homeMembers.welcome.1'); - conv.add('homeMembers.welcome.2'); + conv.add('homeMembers.welcome1'); + conv.add('homeMembers.welcome2'); }); app.handle('home_members_lvl2__intent__listen_audiobook_lvl2', (conv) => { @@ -339,7 +347,7 @@ app.handle("ask_to_resume_listening_at_last_offset", async (conv) => { // const date = history.d; // TODO: use the date info - conv.add('ask_resume_last_offset'); + conv.add('player.askResumeLastOffset'); // wait intent } else { @@ -367,7 +375,7 @@ app.handle("ask_to_resume_listening_at_last_offset__intent__no", async (conv) => app.handle('search', (conv) => { - conv.add('search'); + conv.add('homeMembers.search'); // wait query intent }); @@ -485,7 +493,7 @@ app.handle("player", async (conv) => { // //////////////////////// -app.handle('player__intent__resume_listening_player ', (conv) => { +app.handle('player__intent__resume_listening_player', (conv) => { persistMediaPlayer(conv); // // Acknowledge pause/stop @@ -569,7 +577,7 @@ app.handle('media_status', (conv) => { })); break; default: - conv.add('mediaStatus.notCorrect'); + conv.add('player.mediaStatus.notCorrect'); } console.log('MediaStatus END'); diff --git a/webhooks/functions/src/service/listGroups.ts b/webhooks/functions/src/service/listGroups.ts index 43073577..d535156f 100644 --- a/webhooks/functions/src/service/listGroups.ts +++ b/webhooks/functions/src/service/listGroups.ts @@ -2,6 +2,7 @@ import {TSdkScene} from '../sdk'; import {IConversationWithParams} from '../type'; import {getGroupsFromFeed, isValidHttpUrl} from '../utils'; import {ok} from 'assert'; +import {t} from '../translation'; export async function listGroups(url: string, conv: IConversationWithParams, nextScene: TSdkScene, errorScene: TSdkScene = conv.scene.name) { ok(isValidHttpUrl(url), 'url not valid'); @@ -11,11 +12,11 @@ export async function listGroups(url: string, conv: IConversationWithParams, nex const length = list.length; if (length > 1) { conv.scene.next.name = nextScene; - conv.add('list.numberPublication', {length}); + conv.add('homeMembers.list.numberPublication', {length}); let text = ''; list.map(({title}, i) => { - text += `numero ${i + 1} : ${title}\n`; + text += t('homeMembers.list.numero', {i: i + 1, title}); }); conv.add('free', {text}); } else if (length === 1) { @@ -23,6 +24,6 @@ export async function listGroups(url: string, conv: IConversationWithParams, nex conv.user.params.selection.url = list[0].groupUrl; } else { conv.scene.next.name = errorScene; - conv.add('noResult'); + conv.add('homeMembers.list.noResult'); } } diff --git a/webhooks/functions/src/service/listPublication.ts b/webhooks/functions/src/service/listPublication.ts index 9466de7d..697aae62 100644 --- a/webhooks/functions/src/service/listPublication.ts +++ b/webhooks/functions/src/service/listPublication.ts @@ -2,6 +2,7 @@ import {TSdkScene} from '../sdk'; import {IConversationWithParams} from '../type'; import {getPubsFromFeed, isValidHttpUrl} from '../utils'; import {ok} from 'assert'; +import {t} from '../translation'; export async function listPublication(url: string, conv: IConversationWithParams, nextScene: TSdkScene, errorScene: TSdkScene = conv.scene.name) { ok(isValidHttpUrl(url), 'url not valid'); @@ -11,11 +12,12 @@ export async function listPublication(url: string, conv: IConversationWithParams const length = list.length; if (length > 1) { conv.scene.next.name = nextScene; - conv.add('list.numberPublication', {length}); + conv.add('homeMembers.list.numberPublication', {length}); let text = ''; list.map(({title, author}, i) => { - text += `numero ${i + 1} : ${title} ${author ? `de ${author}` : ''}\n`; + text += t('homeMembers.list.numeroWithAuthor', + {i: i + 1, title, author: author ? t('homeMembers.list.numeroWithAuthorOf', {author}) : ''}); }); conv.add('free', {text}); } else if (length === 1) { @@ -23,6 +25,6 @@ export async function listPublication(url: string, conv: IConversationWithParams conv.user.params.player.current.url = list[0].webpuburl; } else { conv.scene.next.name = errorScene; - conv.add('noResult'); + conv.add('homeMembers.list.noResult'); } } diff --git a/webhooks/functions/src/service/selectGroups.ts b/webhooks/functions/src/service/selectGroups.ts index cbe2ca8c..5671b17d 100644 --- a/webhooks/functions/src/service/selectGroups.ts +++ b/webhooks/functions/src/service/selectGroups.ts @@ -8,7 +8,7 @@ export async function selectGroup(url: string, number: number, conv: IConversati const group = list[number - 1]; if (!group) { console.log('NO GROUPS found !!'); - conv.add('wrongNumber', {number}); + conv.add('homeMembers.list.wrongNumber', {number}); conv.scene.next.name = conv.scene.name; // loop selection or search return; diff --git a/webhooks/functions/src/service/selectPublication.ts b/webhooks/functions/src/service/selectPublication.ts index 663c48f0..c317ae2b 100644 --- a/webhooks/functions/src/service/selectPublication.ts +++ b/webhooks/functions/src/service/selectPublication.ts @@ -8,7 +8,7 @@ export async function selectPublication(url: string, number: number, conv: IConv const pub = list[number - 1]; if (!pub) { console.log('NO PUBS found !!'); - conv.add('wrongNumber', {number}); + conv.add('homeMembers.list.wrongNumber', {number}); conv.scene.next.name = conv.scene.name; // loop selection or search return; diff --git a/webhooks/functions/src/translation/fr/fr.json b/webhooks/functions/src/translation/fr/fr.json new file mode 100644 index 00000000..ea824228 --- /dev/null +++ b/webhooks/functions/src/translation/fr/fr.json @@ -0,0 +1,56 @@ +{ + "error": { + "bearerTokenNotDefined": "Aucun identifiant défini", + "catch": "une erreur s'est produite", + "convadd": "conv.add value incorrect: {{error}}", + "urlNotValid": "url non définis ou invalide {{url}}", + "noQuery": "aucune requete demandée", + "webpubNotDefined": "webpub non définis", + "selectionListNotDefined": "selection list url non définie", + "selectionPubNotDefined": "selection url non définie", + "selectionNotAvailable": "selection non disponible" + }, + "main": { + "welcome": "Que voulez-vous faire ? Vous pouvez dire informations ou espace membres" + }, + "home": { + "information": "Voici les informations sur l'association" + }, + "homeMembers": { + "welcome1": "Bienvenue dans l'espace membres. Les commandes possibles sont: sélection, lecture, recherche.", + "welcome2": "Que voulez-vous faire ?", + "resumeAudiobook": { + "noCurrentListening": "aucune lecture en cours" + }, + "selection": { + "welcome": "Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre, Que voulez-vous faire ?", + "publication": "Pour choisir une publication dite son numéro", + "listAfterSelection": "Pour choisir une sélection dite son numéro" + }, + "list": { + "wrongNumber": "Le numéro {{number}} est inconnu. Veuillez choisir un autre numéro.", + "numberPublication": "Il y a {{length}} publications :\n", + "numero": "numéro {{i}} : {{title}}\n", + "numeroWithAuthor": "numéro {{i}} : {{title}} {{author}}\n", + "numeroWithAuthorOf": "de {{author}}", + "noResult": "aucun résultat trouvé" + }, + "search": "Que voulez-vous écouter ? Par exemple Zola" + }, + "player": { + "askResumeLastOffset": "Voulez-vous reprendre la lecture là où elle s'était arrêtée ?", + "mediaStatus": { + "notCorrect": "media status incorrect" + }, + "remaining": { + "hoursAndMinute": "il reste {{hours}} heures et {{minutes}} minutes", + "minute": "il reste {{minutes}} minutes" + } + }, + "test": { + "player": "test player {{nb}}", + "setupSdk": "setup test {{nb}}", + "webhook": "webhook work: {{message}}" + }, + "free": "{{text}}" +} \ No newline at end of file diff --git a/webhooks/functions/src/translation/index.ts b/webhooks/functions/src/translation/index.ts new file mode 100644 index 00000000..cd123101 --- /dev/null +++ b/webhooks/functions/src/translation/index.ts @@ -0,0 +1,21 @@ +import i18next from 'i18next'; +import * as frTranslation from './fr/fr.json'; +import {Translations} from './../typings/i18n'; +import {DEFAULT_LANGUAGE} from '../constants'; + +i18next.init({ + resources: { + 'fr': { + translation: frTranslation, + }, + }, + fallbackLng: DEFAULT_LANGUAGE, +}); + +export type TI18nKey = Translations['keys']['fr']; + +export const i18n = i18next; + +export const t = i18n.t as (key: TI18nKey, options? : object) => any; + +i18n.t = t as any; diff --git a/webhooks/functions/src/type.ts b/webhooks/functions/src/type.ts index 8157f117..9e3a875f 100644 --- a/webhooks/functions/src/type.ts +++ b/webhooks/functions/src/type.ts @@ -1,7 +1,7 @@ import { ConversationV3 } from "@assistant/conversation"; import { Media } from "@assistant/conversation/dist/api/schema"; import { User, Scene } from "@assistant/conversation/dist/conversation/handler"; -import { TI18nKey } from "./constants"; +import { TI18nKey } from "./translation"; import { StorageDto } from "./model/storage.dto"; import { TSdkScene } from "./sdk"; diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts new file mode 100644 index 00000000..cd05656a --- /dev/null +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +// DO NOT EDIT! This file is generated with "typed-18next" tool. + +export interface Translations { + keys: { + "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberPublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.search" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "test.player" | "test.setupSdk" | "test.webhook" | "free" + }; + keysWithNS: { + "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.search" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" + }; +} diff --git a/webhooks/functions/tsconfig.json b/webhooks/functions/tsconfig.json index 7a7f7645..5cb7356c 100644 --- a/webhooks/functions/tsconfig.json +++ b/webhooks/functions/tsconfig.json @@ -9,7 +9,8 @@ "moduleResolution": "node", "outDir": "build", "experimentalDecorators": true, - "strictNullChecks": true + "strictNullChecks": true, + "resolveJsonModule": true }, "include": [ "src/**/*" From 7522be41fbe3282559a39f731f3bc46a67967e91 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 25 Nov 2021 18:44:27 +0100 Subject: [PATCH 040/180] fix: i18n' --- webhooks/functions/src/translation/index.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/webhooks/functions/src/translation/index.ts b/webhooks/functions/src/translation/index.ts index cd123101..8883b5d5 100644 --- a/webhooks/functions/src/translation/index.ts +++ b/webhooks/functions/src/translation/index.ts @@ -1,4 +1,4 @@ -import i18next from 'i18next'; +import * as i18next from 'i18next'; import * as frTranslation from './fr/fr.json'; import {Translations} from './../typings/i18n'; import {DEFAULT_LANGUAGE} from '../constants'; @@ -17,5 +17,3 @@ export type TI18nKey = Translations['keys']['fr']; export const i18n = i18next; export const t = i18n.t as (key: TI18nKey, options? : object) => any; - -i18n.t = t as any; From 14bffb62df5e1d78ab4fb5169fe9c88fc659897a Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 25 Nov 2021 19:03:21 +0100 Subject: [PATCH 041/180] fix: i18n --- webhooks/functions/src/index.ts | 2 +- webhooks/functions/src/translation/fr/fr.json | 5 +++-- webhooks/functions/src/typings/i18n.d.ts | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 7b00b64b..e2d148b2 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -160,7 +160,7 @@ app.handle('main', (conv) => { app.handle('home_lvl1', (conv) => { - conv.add('main.welcome'); + conv.add('home.welcome'); // wait intent // conv.scene.next.name diff --git a/webhooks/functions/src/translation/fr/fr.json b/webhooks/functions/src/translation/fr/fr.json index ea824228..c77ac498 100644 --- a/webhooks/functions/src/translation/fr/fr.json +++ b/webhooks/functions/src/translation/fr/fr.json @@ -11,10 +11,11 @@ "selectionNotAvailable": "selection non disponible" }, "main": { - "welcome": "Que voulez-vous faire ? Vous pouvez dire informations ou espace membres" + "welcome": "Bienvenue dans l'application d'écoute de livre audio valentin audio" }, "home": { - "information": "Voici les informations sur l'association" + "information": "Voici les informations sur l'association", + "welcome": "Que voulez-vous faire ? Vous pouvez dire informations ou espace membres" }, "homeMembers": { "welcome1": "Bienvenue dans l'espace membres. Les commandes possibles sont: sélection, lecture, recherche.", diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index cd05656a..9c138110 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,9 +3,9 @@ export interface Translations { keys: { - "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberPublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.search" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "test.player" | "test.setupSdk" | "test.webhook" | "free" + "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberPublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.search" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.search" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" + "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.search" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } From 634d16fa870cffdfee127a9357fdb902dcf6ca16 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 25 Nov 2021 19:04:26 +0100 Subject: [PATCH 042/180] fix: constant --- test/dev/test/constant.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/dev/test/constant.ts b/test/dev/test/constant.ts index d7671179..754a4ec2 100644 --- a/test/dev/test/constant.ts +++ b/test/dev/test/constant.ts @@ -4,7 +4,7 @@ import {ok} from 'assert'; export const DEFAULT_LOCALE = 'fr-FR'; export const DEFAULT_SURFACE = 'PHONE'; -export const HOME_PROMPT = "Bienvenue dans l'application d'écoute de livre audio valentin hauy"; +export const HOME_PROMPT = "Bienvenue dans l'application d'écoute de livre audio valentin audio"; export const MEMBER_PROMPT = "Bienvenue dans l'espace membres. Les commandes possibles sont: sélection, lecture, recherche. Que voulez-vous faire ?"; export const PROJECT_ID = env['PROJECT_ID'] || ''; From 80a702e3014045382a6cd55480742559675f4832 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 25 Nov 2021 19:29:03 +0100 Subject: [PATCH 043/180] fix: translation --- webhooks/functions/src/translation/fr/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webhooks/functions/src/translation/fr/fr.json b/webhooks/functions/src/translation/fr/fr.json index c77ac498..619e7208 100644 --- a/webhooks/functions/src/translation/fr/fr.json +++ b/webhooks/functions/src/translation/fr/fr.json @@ -18,7 +18,7 @@ "welcome": "Que voulez-vous faire ? Vous pouvez dire informations ou espace membres" }, "homeMembers": { - "welcome1": "Bienvenue dans l'espace membres. Les commandes possibles sont: sélection, lecture, recherche.", + "welcome1": "Bienvenue dans l'espace membres. Les commandes possibles sont: sélection, lecture, recherche. ", "welcome2": "Que voulez-vous faire ?", "resumeAudiobook": { "noCurrentListening": "aucune lecture en cours" From 431fde6f31c72859af4eef5cdc7d583649b4a38d Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 25 Nov 2021 19:58:19 +0100 Subject: [PATCH 044/180] fix: i18n escaping --- webhooks/functions/src/translation/fr/fr.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/webhooks/functions/src/translation/fr/fr.json b/webhooks/functions/src/translation/fr/fr.json index 619e7208..73ad0014 100644 --- a/webhooks/functions/src/translation/fr/fr.json +++ b/webhooks/functions/src/translation/fr/fr.json @@ -31,9 +31,9 @@ "list": { "wrongNumber": "Le numéro {{number}} est inconnu. Veuillez choisir un autre numéro.", "numberPublication": "Il y a {{length}} publications :\n", - "numero": "numéro {{i}} : {{title}}\n", - "numeroWithAuthor": "numéro {{i}} : {{title}} {{author}}\n", - "numeroWithAuthorOf": "de {{author}}", + "numero": "numéro {{i}} : {{- title}}\n", + "numeroWithAuthor": "numéro {{i}} : {{- title}} {{- author}}\n", + "numeroWithAuthorOf": "de {{- author}}", "noResult": "aucun résultat trouvé" }, "search": "Que voulez-vous écouter ? Par exemple Zola" @@ -51,7 +51,7 @@ "test": { "player": "test player {{nb}}", "setupSdk": "setup test {{nb}}", - "webhook": "webhook work: {{message}}" + "webhook": "webhook work: {{- message}}" }, - "free": "{{text}}" + "free": "{{- text}}" } \ No newline at end of file From 6e881832d9d54166ec6e03ab7d0af87199ccbf69 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 25 Nov 2021 20:17:23 +0100 Subject: [PATCH 045/180] fix i18n --- test/dev/test/test12.ts | 2 +- test/dev/test/test3.ts | 2 +- test/dev/test/test4.ts | 2 +- test/dev/test/test9.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/dev/test/test12.ts b/test/dev/test/test12.ts index 45fe7753..79c8ab39 100644 --- a/test/dev/test/test12.ts +++ b/test/dev/test/test12.ts @@ -33,7 +33,7 @@ describe('My Action Test Suite', function () { await test.sendQuery('zola'); - await test.assertSpeech(`Il y a 2 publications :\n Pour choisir une publication dite son numéronumero 1 : Thérèse Raquin de Emile Zola\nnumero 2 : L'assommoir de Emile Zola\n`); + await test.assertSpeech(`Il y a 2 publications :\n Pour choisir une publication dite son numéronuméro 1 : Thérèse Raquin de Emile Zola\nnuméro 2 : L'assommoir de Emile Zola\n`); await test.sendQuery('0'); diff --git a/test/dev/test/test3.ts b/test/dev/test/test3.ts index d0592e76..b8025977 100644 --- a/test/dev/test/test3.ts +++ b/test/dev/test/test3.ts @@ -31,7 +31,7 @@ describe('My Action Test Suite', function () { await test.sendQuery('zola'); - await test.assertSpeech(`Il y a 2 publications :\n Pour choisir une publication dite son numéronumero 1 : Thérèse Raquin de Emile Zola\nnumero 2 : L'assommoir de Emile Zola\n`); + await test.assertSpeech(`Il y a 2 publications :\n Pour choisir une publication dite son numéronuméro 1 : Thérèse Raquin de Emile Zola\nnuméro 2 : L'assommoir de Emile Zola\n`); await test.sendQuery('0'); diff --git a/test/dev/test/test4.ts b/test/dev/test/test4.ts index d40cf70a..331c3ea2 100644 --- a/test/dev/test/test4.ts +++ b/test/dev/test/test4.ts @@ -33,7 +33,7 @@ describe('My Action Test Suite', function () { await test.sendQuery('zola'); - await test.assertSpeech(`Il y a 2 publications :\n Pour choisir une publication dite son numéronumero 1 : Thérèse Raquin de Emile Zola\nnumero 2 : L'assommoir de Emile Zola\n`); + await test.assertSpeech(`Il y a 2 publications :\n Pour choisir une publication dite son numéronuméro 1 : Thérèse Raquin de Emile Zola\nnuméro 2 : L'assommoir de Emile Zola\n`); await test.sendQuery('0'); diff --git a/test/dev/test/test9.ts b/test/dev/test/test9.ts index 27169574..1470abf0 100644 --- a/test/dev/test/test9.ts +++ b/test/dev/test/test9.ts @@ -29,7 +29,7 @@ describe('My Action Test Suite', function () { test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre, Que voulez-vous faire ?`); await test.sendQuery(`ma liste`); - test.assertSpeech(`Il y a 2 publications :\n Pour choisir une publication dite son numéronumero 1 : L'assommoir de Emile Zola\nnumero 2 : Du contrat social de Rousseau\n`); + test.assertSpeech(`Il y a 2 publications :\n Pour choisir une publication dite son numéronuméro 1 : L'assommoir de Emile Zola\nnuméro 2 : Du contrat social de Rousseau\n`); await test.sendQuery(`2`); From 749f3f028208ce2322c5e598fecc8c6d3ae04dac Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 13 Dec 2021 14:06:55 +0100 Subject: [PATCH 046/180] locale (PR #14) --- test/dev/test/constant.ts | 4 +-- test/dev/test/test10.ts | 2 +- test/dev/test/test11.ts | 2 +- test/dev/test/test12.ts | 4 +-- test/dev/test/test13.ts | 2 +- test/dev/test/test2.ts | 2 +- test/dev/test/test3.ts | 4 +-- test/dev/test/test4.ts | 4 +-- test/dev/test/test9.ts | 4 +-- webhooks/functions/src/translation/fr/fr.json | 32 +++++++++---------- 10 files changed, 30 insertions(+), 30 deletions(-) diff --git a/test/dev/test/constant.ts b/test/dev/test/constant.ts index 754a4ec2..bba04e70 100644 --- a/test/dev/test/constant.ts +++ b/test/dev/test/constant.ts @@ -4,8 +4,8 @@ import {ok} from 'assert'; export const DEFAULT_LOCALE = 'fr-FR'; export const DEFAULT_SURFACE = 'PHONE'; -export const HOME_PROMPT = "Bienvenue dans l'application d'écoute de livre audio valentin audio"; -export const MEMBER_PROMPT = "Bienvenue dans l'espace membres. Les commandes possibles sont: sélection, lecture, recherche. Que voulez-vous faire ?"; +export const HOME_PROMPT = "Bienvenue dans Valentin Audio."; +export const MEMBER_PROMPT = "Les commandes possibles sont: sélection, lecture, recherche. Que voulez-vous faire ?"; export const PROJECT_ID = env['PROJECT_ID'] || ''; export const TRIGGER_PHRASE = 'Parler avec valentin audio dev'; diff --git a/test/dev/test/test10.ts b/test/dev/test/test10.ts index a14ced9e..b254b94b 100644 --- a/test/dev/test/test10.ts +++ b/test/dev/test/test10.ts @@ -26,7 +26,7 @@ describe('My Action Test Suite', function () { await test.sendQuery(`sélections`); - test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre, Que voulez-vous faire ?`); + test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre. Que voulez-vous faire ?`); await test.sendQuery(`selections thématiques`); test.assertSpeech(``); diff --git a/test/dev/test/test11.ts b/test/dev/test/test11.ts index ad2ba9a6..a51c1f76 100644 --- a/test/dev/test/test11.ts +++ b/test/dev/test/test11.ts @@ -26,7 +26,7 @@ describe('My Action Test Suite', function () { await test.sendQuery(`sélections`); - test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre, Que voulez-vous faire ?`); + test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre. Que voulez-vous faire ?`); await test.sendQuery(`selections par genre`); diff --git a/test/dev/test/test12.ts b/test/dev/test/test12.ts index 79c8ab39..2bd583ad 100644 --- a/test/dev/test/test12.ts +++ b/test/dev/test/test12.ts @@ -33,11 +33,11 @@ describe('My Action Test Suite', function () { await test.sendQuery('zola'); - await test.assertSpeech(`Il y a 2 publications :\n Pour choisir une publication dite son numéronuméro 1 : Thérèse Raquin de Emile Zola\nnuméro 2 : L'assommoir de Emile Zola\n`); + await test.assertSpeech(`J'ai trouvé 2 publications.\n Pour choisir une publication, dites son numéro.numéro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n`); await test.sendQuery('0'); - await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. Pour choisir une publication dite son numéro`); + await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. Pour choisir une publication, dites son numéro.`); test.assertScene('select_pub_after_search'); diff --git a/test/dev/test/test13.ts b/test/dev/test/test13.ts index 52d900f0..9d1ad327 100644 --- a/test/dev/test/test13.ts +++ b/test/dev/test/test13.ts @@ -26,7 +26,7 @@ describe('My Action Test Suite', function () { await test.sendQuery(`sélections`); - test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre, Que voulez-vous faire ?`); + test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre. Que voulez-vous faire ?`); await test.sendQuery(`selections par genre`); diff --git a/test/dev/test/test2.ts b/test/dev/test/test2.ts index 670fd1c6..d6e2dfc7 100644 --- a/test/dev/test/test2.ts +++ b/test/dev/test/test2.ts @@ -31,7 +31,7 @@ describe('My Action Test Suite', function () { await test.sendQuery('test avec aucune publication renvoyées'); - await test.assertSpeech(`aucun résultat trouvé Que voulez-vous écouter ? Par exemple Zola`); + await test.assertSpeech(`aucun résultat trouvé Que voulez-vous écouter ? Par exemple Zola.`); // // resp = test.getLatestResponse(); diff --git a/test/dev/test/test3.ts b/test/dev/test/test3.ts index b8025977..704e9d54 100644 --- a/test/dev/test/test3.ts +++ b/test/dev/test/test3.ts @@ -31,11 +31,11 @@ describe('My Action Test Suite', function () { await test.sendQuery('zola'); - await test.assertSpeech(`Il y a 2 publications :\n Pour choisir une publication dite son numéronuméro 1 : Thérèse Raquin de Emile Zola\nnuméro 2 : L'assommoir de Emile Zola\n`); + await test.assertSpeech(`J'ai trouvé 2 publications.\n Pour choisir une publication, dites son numéro.numéro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n`); await test.sendQuery('0'); - await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. Pour choisir une publication dite son numéro`); + await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. Pour choisir une publication, dites son numéro.`); test.assertScene('select_pub_after_search'); diff --git a/test/dev/test/test4.ts b/test/dev/test/test4.ts index 331c3ea2..51e1ee6e 100644 --- a/test/dev/test/test4.ts +++ b/test/dev/test/test4.ts @@ -33,11 +33,11 @@ describe('My Action Test Suite', function () { await test.sendQuery('zola'); - await test.assertSpeech(`Il y a 2 publications :\n Pour choisir une publication dite son numéronuméro 1 : Thérèse Raquin de Emile Zola\nnuméro 2 : L'assommoir de Emile Zola\n`); + await test.assertSpeech(`J'ai trouvé 2 publications.\n Pour choisir une publication, dites son numéro.numéro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n`); await test.sendQuery('0'); - await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. Pour choisir une publication dite son numéro`); + await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. Pour choisir une publication, dites son numéro.`); test.assertScene('select_pub_after_search'); diff --git a/test/dev/test/test9.ts b/test/dev/test/test9.ts index 1470abf0..c62fba1d 100644 --- a/test/dev/test/test9.ts +++ b/test/dev/test/test9.ts @@ -26,10 +26,10 @@ describe('My Action Test Suite', function () { await test.sendQuery(`sélections`); - test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre, Que voulez-vous faire ?`); + test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre. Que voulez-vous faire ?`); await test.sendQuery(`ma liste`); - test.assertSpeech(`Il y a 2 publications :\n Pour choisir une publication dite son numéronuméro 1 : L'assommoir de Emile Zola\nnuméro 2 : Du contrat social de Rousseau\n`); + test.assertSpeech(`J'ai trouvé 2 publications.\n Pour choisir une publication, dites son numéro.numéro 1 : L'assommoir de Emile Zola\nnuméro 2 : Du contrat social de Rousseau\n`); await test.sendQuery(`2`); diff --git a/webhooks/functions/src/translation/fr/fr.json b/webhooks/functions/src/translation/fr/fr.json index 73ad0014..09efb241 100644 --- a/webhooks/functions/src/translation/fr/fr.json +++ b/webhooks/functions/src/translation/fr/fr.json @@ -11,41 +11,41 @@ "selectionNotAvailable": "selection non disponible" }, "main": { - "welcome": "Bienvenue dans l'application d'écoute de livre audio valentin audio" + "welcome": "Bienvenue dans Valentin Audio." }, "home": { - "information": "Voici les informations sur l'association", - "welcome": "Que voulez-vous faire ? Vous pouvez dire informations ou espace membres" + "information": "Vous accédez à la plateforme de démonstration du projet Lis mon Livre du laboratoire européen de lecture numérique (éderlab). Le service est actuellement réservé aux testeurs de l’application. Ce texte sera à terme remplacé par des informations génériques sur la manière d’accéder à l’espace membre.", + "welcome": "Que voulez-vous faire ? Vous pouvez dire informations ou espace membres." }, "homeMembers": { - "welcome1": "Bienvenue dans l'espace membres. Les commandes possibles sont: sélection, lecture, recherche. ", + "welcome1": "Les commandes possibles sont: sélection, lecture, recherche. ", "welcome2": "Que voulez-vous faire ?", "resumeAudiobook": { - "noCurrentListening": "aucune lecture en cours" + "noCurrentListening": "Aucune lecture en cours." }, "selection": { - "welcome": "Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre, Que voulez-vous faire ?", - "publication": "Pour choisir une publication dite son numéro", - "listAfterSelection": "Pour choisir une sélection dite son numéro" + "welcome": "Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre. Que voulez-vous faire ?", + "publication": "Pour choisir une publication, dites son numéro.", + "listAfterSelection": "Pour choisir une sélection, dites son numéro." }, "list": { "wrongNumber": "Le numéro {{number}} est inconnu. Veuillez choisir un autre numéro.", - "numberPublication": "Il y a {{length}} publications :\n", - "numero": "numéro {{i}} : {{- title}}\n", - "numeroWithAuthor": "numéro {{i}} : {{- title}} {{- author}}\n", + "numberPublication": "J'ai trouvé {{length}} publications.\n", + "numero": "numéro {{i}} : {{- title}}.\n", + "numeroWithAuthor": "numéro {{i}} : {{- title}} {{- author}}.\n", "numeroWithAuthorOf": "de {{- author}}", - "noResult": "aucun résultat trouvé" + "noResult": "Aucun résultat trouvé." }, - "search": "Que voulez-vous écouter ? Par exemple Zola" + "search": "Que voulez-vous écouter ? Par exemple Zola." }, "player": { "askResumeLastOffset": "Voulez-vous reprendre la lecture là où elle s'était arrêtée ?", "mediaStatus": { - "notCorrect": "media status incorrect" + "notCorrect": "état de lecture incorrect." }, "remaining": { - "hoursAndMinute": "il reste {{hours}} heures et {{minutes}} minutes", - "minute": "il reste {{minutes}} minutes" + "hoursAndMinute": "Il reste {{hours}} heures et {{minutes}} minutes.", + "minute": "Il reste {{minutes}} minutes." } }, "test": { From c5b9a3406356e4244a7ee49843946f5ab0e2a3e4 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 13 Dec 2021 14:07:45 +0100 Subject: [PATCH 047/180] player (PR #13) --- sdk/test/custom/intents/listen_toc.yaml | 5 ++ sdk/test/custom/intents/menu.yaml | 3 + .../intents/resume_listening_player.yaml | 2 + sdk/test/custom/scenes/player.yaml | 6 ++ .../webhooks/ActionsOnGoogleFulfillment.yaml | 2 + webhooks/functions/src/index.ts | 55 ++++++++++++++++++- 6 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 sdk/test/custom/intents/listen_toc.yaml create mode 100644 sdk/test/custom/intents/menu.yaml diff --git a/sdk/test/custom/intents/listen_toc.yaml b/sdk/test/custom/intents/listen_toc.yaml new file mode 100644 index 00000000..68285400 --- /dev/null +++ b/sdk/test/custom/intents/listen_toc.yaml @@ -0,0 +1,5 @@ +trainingPhrases: +- table des matières +- lis la table des matières +- lis moi la table des matières +- lis moi la toc diff --git a/sdk/test/custom/intents/menu.yaml b/sdk/test/custom/intents/menu.yaml new file mode 100644 index 00000000..fade5c08 --- /dev/null +++ b/sdk/test/custom/intents/menu.yaml @@ -0,0 +1,3 @@ +trainingPhrases: +- revenir au menu +- menu diff --git a/sdk/test/custom/intents/resume_listening_player.yaml b/sdk/test/custom/intents/resume_listening_player.yaml index 2cd0b674..d03ff0d7 100644 --- a/sdk/test/custom/intents/resume_listening_player.yaml +++ b/sdk/test/custom/intents/resume_listening_player.yaml @@ -1,3 +1,5 @@ trainingPhrases: +- continue +- reprends - reprend la lecture - reprendre la lecture diff --git a/sdk/test/custom/scenes/player.yaml b/sdk/test/custom/scenes/player.yaml index 9f4e8d93..4f882dde 100644 --- a/sdk/test/custom/scenes/player.yaml +++ b/sdk/test/custom/scenes/player.yaml @@ -5,6 +5,12 @@ intentEvents: - handler: webhookHandler: player__intent__remaining_time_player intent: remaing_time_player +- handler: + webhookHandler: player__intent__listen_toc + intent: listen_toc +- handler: + webhookHandler: player__intent__menu + intent: menu - handler: webhookHandler: media_status intent: actions.intent.MEDIA_STATUS_FINISHED diff --git a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml index fec8a8f3..0474f3e5 100644 --- a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml @@ -38,6 +38,8 @@ handlers: - name: select_pub_after_search__intent__stop - name: select_pub_after_selection__intent__stop - name: select_list_after_list_selection__intent__stop +- name: player__intent__listen_toc +- name: player__intent__menu httpsEndpoint: baseUrl: https://us-central1-valentin-5.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index e2d148b2..d4097953 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -449,12 +449,18 @@ app.handle("player", async (conv) => { const webpub = await opds.webpubRequest(url); ok(webpub, 'error.webpubNotDefined'); - const startIndex = (startIndexRaw && startIndexRaw <= webpub.readingOrders.length) + let startIndex = (startIndexRaw && startIndexRaw > -1 && startIndexRaw <= webpub.readingOrders.length) ? startIndexRaw : 0; - const startTime = (startTimeRaw && startTimeRaw <= (webpub.readingOrders[startIndex].duration || Infinity)) - ? startTimeRaw + const startTime = (startTimeRaw && startTimeRaw > -1) + ? startTimeRaw <= (webpub.readingOrders[startIndex].duration || Infinity) + ? startTimeRaw + : (startIndex += 1, startTimeRaw) + : 0; + + startIndex = startIndex <= webpub.readingOrders.length + ? startIndex : 0; const mediaObjects = webpub.readingOrders @@ -504,6 +510,40 @@ app.handle('player__intent__resume_listening_player', (conv) => { conv.scene.next.name = 'player'; }); +// overhided by the google nest player +// 'avance' : avance de x seconds +// 'repete' : repete la track +// 'avance de 30 secondes : ne fait rien +// +// app.handle('player__intent__repeat_player', (conv) => { +// persistMediaPlayer(conv); + +// if (conv.user.params.player.current.time) +// conv.user.params.player.current.time -= 30; + +// conv.scene.next.name = 'player'; +// }); + +// app.handle('player__intent__jump_30sec_player', (conv) => { +// persistMediaPlayer(conv); + +// if (conv.user.params.player.current.time) +// conv.user.params.player.current.time += 30; + +// conv.scene.next.name = 'player'; +// }); + +app.handle('player__intent__menu', (conv) => { + persistMediaPlayer(conv); + + // Acknowledge pause/stop + conv.add(new Media({ + mediaType: MediaType.MediaStatusACK, + })); + + conv.scene.next.name = "home_members_lvl2"; +}); + app.handle('player__intent__remaining_time_player', async (conv) => { persistMediaPlayer(conv); @@ -569,12 +609,21 @@ app.handle('media_status', (conv) => { // void break; case 'PAUSED': + persistMediaPlayer(conv); + // Acknowledge pause/stop + conv.add(new Media({ + mediaType: MediaType.MediaStatusACK, + })); + + break; case 'STOPPED': persistMediaPlayer(conv); // Acknowledge pause/stop conv.add(new Media({ mediaType: MediaType.MediaStatusACK, })); + + conv.scene.next.name = "home_members_lvl2"; break; default: conv.add('player.mediaStatus.notCorrect'); From efb4eca27b37f19acca92e2afad3c31cafc4bc2c Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Fri, 17 Dec 2021 15:38:15 +0100 Subject: [PATCH 048/180] next intent in select_publication scene (PR #15) --- sdk/test/custom/intents/next.yaml | 2 + sdk/test/custom/intents/repeat.yaml | 2 + .../selection_all_publication_lvl3.yaml | 2 + ..._list_selection.yaml => select_group.yaml} | 6 +- .../scenes/select_pub_after_selection.yaml | 64 ------- ...er_search.yaml => select_publication.yaml} | 14 +- sdk/test/custom/scenes/selection_lvl3.yaml | 3 + .../webhooks/ActionsOnGoogleFulfillment.yaml | 21 ++- webhooks/functions/src/constants.ts | 1 + webhooks/functions/src/index.ts | 161 ++++++++++-------- webhooks/functions/src/model/storage.dto.ts | 19 +-- .../functions/src/model/storage.interface.ts | 6 - webhooks/functions/src/model/storage.test.ts | 56 +++--- webhooks/functions/src/sdk.d.ts | 4 +- webhooks/functions/src/service/listGroups.ts | 15 +- .../functions/src/service/listPublication.ts | 30 ++-- .../functions/src/service/selectGroups.ts | 4 +- webhooks/functions/src/translation/fr/fr.json | 13 +- webhooks/functions/src/type.ts | 6 +- webhooks/functions/src/typings/i18n.d.ts | 4 +- webhooks/functions/src/utils/index.ts | 26 ++- 21 files changed, 217 insertions(+), 242 deletions(-) create mode 100644 sdk/test/custom/intents/next.yaml create mode 100644 sdk/test/custom/intents/repeat.yaml create mode 100644 sdk/test/custom/intents/selection_all_publication_lvl3.yaml rename sdk/test/custom/scenes/{select_list_after_list_selection.yaml => select_group.yaml} (89%) delete mode 100644 sdk/test/custom/scenes/select_pub_after_selection.yaml rename sdk/test/custom/scenes/{select_pub_after_search.yaml => select_publication.yaml} (80%) diff --git a/sdk/test/custom/intents/next.yaml b/sdk/test/custom/intents/next.yaml new file mode 100644 index 00000000..79a4e281 --- /dev/null +++ b/sdk/test/custom/intents/next.yaml @@ -0,0 +1,2 @@ +trainingPhrases: +- suivant diff --git a/sdk/test/custom/intents/repeat.yaml b/sdk/test/custom/intents/repeat.yaml new file mode 100644 index 00000000..bc2af48e --- /dev/null +++ b/sdk/test/custom/intents/repeat.yaml @@ -0,0 +1,2 @@ +trainingPhrases: +- répéter diff --git a/sdk/test/custom/intents/selection_all_publication_lvl3.yaml b/sdk/test/custom/intents/selection_all_publication_lvl3.yaml new file mode 100644 index 00000000..97be19f7 --- /dev/null +++ b/sdk/test/custom/intents/selection_all_publication_lvl3.yaml @@ -0,0 +1,2 @@ +trainingPhrases: +- toute les publications diff --git a/sdk/test/custom/scenes/select_list_after_list_selection.yaml b/sdk/test/custom/scenes/select_group.yaml similarity index 89% rename from sdk/test/custom/scenes/select_list_after_list_selection.yaml rename to sdk/test/custom/scenes/select_group.yaml index dae8d20c..bca991f5 100644 --- a/sdk/test/custom/scenes/select_list_after_list_selection.yaml +++ b/sdk/test/custom/scenes/select_group.yaml @@ -1,6 +1,6 @@ intentEvents: - handler: - webhookHandler: select_list_after_list_selection__intent__stop + webhookHandler: select_group__intent__stop intent: stop - handler: staticPrompt: @@ -51,9 +51,9 @@ intentEvents: - speech: je n’ai pas compris le numéro intent: actions.intent.NO_INPUT_FINAL onEnter: - webhookHandler: select_list_after_list_selection + webhookHandler: select_group onSlotUpdated: - webhookHandler: select_list_after_list_selection__slot__number + webhookHandler: select_group__slot__number slots: - name: number required: true diff --git a/sdk/test/custom/scenes/select_pub_after_selection.yaml b/sdk/test/custom/scenes/select_pub_after_selection.yaml deleted file mode 100644 index 520e74d4..00000000 --- a/sdk/test/custom/scenes/select_pub_after_selection.yaml +++ /dev/null @@ -1,64 +0,0 @@ -intentEvents: -- handler: - webhookHandler: select_pub_after_selection__intent__resume_listening_player - intent: resume_listening_player -- handler: - webhookHandler: select_pub_after_selection__intent__stop - intent: stop -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, merci de le répêter - intent: actions.intent.NO_MATCH_1 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, dite un numéro - intent: actions.intent.NO_MATCH_2 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, dite un numéro - intent: actions.intent.NO_MATCH_FINAL -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, dite un numéro - intent: actions.intent.NO_INPUT_1 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, dite un numéro - intent: actions.intent.NO_INPUT_2 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro - intent: actions.intent.NO_INPUT_FINAL -onEnter: - webhookHandler: select_pub_after_selection -onSlotUpdated: - webhookHandler: select_pub_after_selection__slot__number -slots: -- name: number - required: true - type: - name: actions.type.Number diff --git a/sdk/test/custom/scenes/select_pub_after_search.yaml b/sdk/test/custom/scenes/select_publication.yaml similarity index 80% rename from sdk/test/custom/scenes/select_pub_after_search.yaml rename to sdk/test/custom/scenes/select_publication.yaml index b29c202c..15a01006 100644 --- a/sdk/test/custom/scenes/select_pub_after_search.yaml +++ b/sdk/test/custom/scenes/select_publication.yaml @@ -1,10 +1,16 @@ intentEvents: - handler: - webhookHandler: select_pub_after_search__intent__resume_listening_player + webhookHandler: select_publication__intent__resume_listening_player intent: resume_listening_player - handler: - webhookHandler: select_pub_after_search__intent__stop + webhookHandler: select_publication__intent__stop intent: stop +- handler: + webhookHandler: select_publication__intent__next + intent: next +- handler: + webhookHandler: select_publication__intent__repeat + intent: repeat - handler: staticPrompt: candidates: @@ -56,9 +62,9 @@ intentEvents: intent: actions.intent.NO_INPUT_FINAL transitionToScene: search onEnter: - webhookHandler: select_pub_after_search + webhookHandler: select_publication onSlotUpdated: - webhookHandler: select_pub_after_search__slot__number + webhookHandler: select_publication__slot__number slots: - name: number required: true diff --git a/sdk/test/custom/scenes/selection_lvl3.yaml b/sdk/test/custom/scenes/selection_lvl3.yaml index 72d9a35a..72a33a36 100644 --- a/sdk/test/custom/scenes/selection_lvl3.yaml +++ b/sdk/test/custom/scenes/selection_lvl3.yaml @@ -8,5 +8,8 @@ intentEvents: - handler: webhookHandler: selection_lvl3__intent__selection_my_list_lvl3 intent: selection_my_list_lvl3 +- handler: + webhookHandler: selection_lvl3__intent__selection_all_publication_lvl3 + intent: selection_all_publication_lvl3 onEnter: webhookHandler: selection_lvl3 diff --git a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml index 0474f3e5..dba81c2c 100644 --- a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml @@ -17,29 +17,28 @@ handlers: - name: selection_lvl3__intent__selection_thematic_list_lvl3 - name: selection_lvl3__intent__selection_genre_lvl3 - name: selection_lvl3__intent__selection_my_list_lvl3 -- name: select_pub_after_selection -- name: select_pub_after_selection__slot__number -- name: select_pub_after_selection__intent__resume_listening_player -- name: select_list_after_list_selection -- name: select_list_after_list_selection__slot__number - name: ask_to_resume_listening_at_last_offset__intent__yes - name: player__intent__resume_listening_player - name: player__intent__remaining_time_player - name: search - name: search__slot__query - name: search__intent__resume_listening_player -- name: select_pub_after_search__slot__number -- name: select_pub_after_search__intent__resume_listening_player -- name: select_pub_after_search - name: test_player_sdk - name: test_setup_sdk - name: test_webhook - name: ask_to_resume_listening_at_last_offset__intent__no -- name: select_pub_after_search__intent__stop -- name: select_pub_after_selection__intent__stop -- name: select_list_after_list_selection__intent__stop - name: player__intent__listen_toc - name: player__intent__menu +- name: select_publication__slot__number +- name: select_publication__intent__resume_listening_player +- name: select_publication +- name: select_publication__intent__stop +- name: select_publication__intent__next +- name: select_group +- name: select_group__slot__number +- name: select_group__intent__stop +- name: selection_lvl3__intent__selection_all_publication_lvl3 +- name: select_publication__intent__repeat httpsEndpoint: baseUrl: https://us-central1-valentin-5.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/constants.ts b/webhooks/functions/src/constants.ts index 95668b4e..bfadfe72 100644 --- a/webhooks/functions/src/constants.ts +++ b/webhooks/functions/src/constants.ts @@ -1,4 +1,5 @@ +export const ALL_PUBLICATION_LIST_URL = "https://storage.googleapis.com/audiobook_edrlab/navigation/all.json"; export const SELECTION_URL = 'https://storage.googleapis.com/audiobook_edrlab/groups/popular.json'; export const SEARCH_URL = 'https://europe-west1-audiobooks-a6348.cloudfunctions.net/indexer?url=https://storage.googleapis.com/audiobook_edrlab/navigation/all.json&query={query}'; export const THEMATIC_LIST_URL = 'https://storage.googleapis.com/audiobook_edrlab/navigation/thematic_list.json'; diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index d4097953..cf7fb4d4 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -7,7 +7,7 @@ import {ok as _ok} from "assert"; import 'reflect-metadata'; import { pull, push } from "./database"; import { StorageDto } from "./model/storage.dto"; -import { isValidHttpUrl } from "./utils"; +import { getNextLinkFromPublicationsFeed, isPublicationAvailable, isValidHttpUrl } from "./utils"; import { IConversationWithParams, MediaType, OptionalMediaControl, TPromptItem } from "./type"; import { persistMediaPlayer } from "./service/persist"; import { listPublication } from "./service/listPublication"; @@ -15,7 +15,7 @@ import { selectPublication } from "./service/selectPublication"; import { testConversation } from "./conversation/test"; import { listGroups } from "./service/listGroups"; import { selectGroup } from "./service/selectGroups"; -import { GENRE_LIST_URL, SEARCH_URL, SELECTION_URL, THEMATIC_LIST_URL } from "./constants"; +import { ALL_PUBLICATION_LIST_URL, GENRE_LIST_URL, SEARCH_URL, SELECTION_URL, THEMATIC_LIST_URL } from "./constants"; import { i18n, t, TI18nKey } from "./translation"; const BEARER_TOKEN_NOT_DEFINED = "bearer token not defined"; @@ -89,7 +89,13 @@ app.catch((conv, error) => { app.middleware(async (conv: IConversationWithParams) => { if (!conv.session.params) { - conv.session.params = {}; + conv.session.params = { + groupListUrl: "", + pubListUrl: "", + query: "", + nextUrlCounter: 0, + scene: 'home_lvl1', + }; } const locale = conv.user.locale; @@ -235,8 +241,12 @@ app.handle('selection_lvl3', (conv) => { conv.add("homeMembers.selection.welcome"); // reset selection context - conv.user.params.selection.url = undefined; - conv.user.params.selection.topUrl = undefined; + // conv.user.params.selection.url = undefined; + // conv.user.params.selection.topUrl = undefined; + conv.session.params.pubListUrl = ""; + conv.session.params.groupListUrl = ""; + + conv.session.params.scene = 'selection_lvl3'; // wait intent // conv.scene.next.name @@ -244,95 +254,69 @@ app.handle('selection_lvl3', (conv) => { app.handle('selection_lvl3__intent__selection_genre_lvl3', async (conv) => { - // conv.add("sélection par genre"); - const url = GENRE_LIST_URL; - conv.user.params.selection.topUrl = url; - conv.user.params.selection.url = undefined; + conv.session.params.groupListUrl = url; + conv.scene.next.name = 'select_group'; - await listGroups(url, conv, 'select_list_after_list_selection'); }); app.handle('selection_lvl3__intent__selection_thematic_list_lvl3', async (conv) => { - // conv.add('sélection par liste thématique'); - const url = THEMATIC_LIST_URL; - conv.user.params.selection.topUrl = url; - conv.user.params.selection.url = undefined; - - await listGroups(url, conv, 'select_list_after_list_selection'); + conv.session.params.groupListUrl = url; + conv.scene.next.name = 'select_group'; }); app.handle('selection_lvl3__intent__selection_my_list_lvl3', async (conv) => { - const url = SELECTION_URL; - conv.user.params.selection.topUrl = undefined; - conv.user.params.selection.url = url; - - await listPublication(url, conv, 'select_pub_after_selection', 'home_members_lvl2'); + conv.session.params.pubListUrl = SELECTION_URL; + conv.scene.next.name = 'select_publication'; console.log('selection_my_list_lvl3 EXIT'); }); -app.handle('select_pub_after_selection', (conv) => { +app.handle('selection_lvl3__intent__selection_all_publication_lvl3', async (conv) => { - conv.add('homeMembers.selection.publication'); - - // wait slot number or intent + conv.session.params.pubListUrl = ALL_PUBLICATION_LIST_URL; + conv.scene.next.name = 'select_publication'; }); -app.handle('select_list_after_list_selection', (conv) => { +app.handle('select_group', async (conv) => { conv.add('homeMembers.selection.listAfterSelection'); + const url = conv.session.params.groupListUrl; + ok(isValidHttpUrl(url)); + await listGroups(url, conv); + // wait slot number or intent }); -app.handle('select_list_after_list_selection__intent__stop', (conv) => { +app.handle('select_group__intent__stop', (conv) => { conv.scene.next.name = 'home_members_lvl2'; }); -app.handle('select_list_after_list_selection__slot__number', async (conv) => { - console.log('select_publication_number START'); +app.handle('select_group__slot__number', async (conv) => { + console.log('select_group_number START'); const number = conv.intent.params?.number.resolved; - const topUrl = conv.user.params.selection.topUrl; - - ok(topUrl, 'error.selectionListNotDefined'); - await selectGroup(topUrl, number, conv); + const groupUrl = conv.session.params.groupListUrl; + ok(isValidHttpUrl(groupUrl), 'error.selectionListNotDefined'); + const url = await selectGroup(groupUrl, number, conv); - const url = conv.user.params.selection.url; + if (url) { + ok(isValidHttpUrl(url), 'error.selectionPubNotDefined'); - ok(url, 'error.selectionPubNotDefined'); - await listPublication(url, conv, 'select_pub_after_selection'); - - console.log('select_publication_number END'); -}); - - -app.handle('select_pub_after_selection__slot__number', async (conv) => { - console.log('select_publication_number START'); - - const number = conv.intent.params?.number.resolved; - - const url = conv.user.params.selection.url; - ok(url, 'error.selectionNotAvailable'); - await selectPublication(url, number, conv); - - console.log('select_publication_number END'); -}); - -app.handle('select_pub_after_selection__intent__stop', (conv) => { - - conv.scene.next.name = 'home_members_lvl2'; -}); - -app.handle('select_pub_after_selection__intent__resume_listening_player', (conv) => { + conv.session.params.pubListUrl = url; + conv.session.params.nextUrlCounter = 0; + conv.scene.next.name = 'select_publication'; + } else { + // conv.scene.next.name = 'select_group'; + } - conv.scene.next.name = "select_pub_after_selection"; + console.log('select_group_number END'); }); app.handle("ask_to_resume_listening_at_last_offset", async (conv) => { @@ -377,25 +361,32 @@ app.handle('search', (conv) => { conv.add('homeMembers.search'); + conv.session.params.scene = 'search'; + + conv.session.params.pubListUrl = ""; + conv.session.params.groupListUrl = ""; + // wait query intent }); app.handle('search__slot__query', async (conv) => { // void - console.log('search_livre_lvl2 START'); - const query = conv.intent.params?.query.resolved; + console.log('search_slot_query', query); + ok(typeof query === 'string', 'error.noQuery'); conv.session.params.query = query; + // save url to session storage (next link) const url = SEARCH_URL.replace('{query}', encodeURIComponent(query)); console.log('search URL: ', url); - await listPublication(url, conv, 'select_pub_after_search', 'search'); - console.log('search_livre_lvl2 STOP'); + ok(isValidHttpUrl(url)); + conv.session.params.pubListUrl = url; + conv.session.params.nextUrlCounter = 0; + conv.scene.next.name = "select_publication"; - // slot available for research }); app.handle('search__intent__resume_listening_player', (conv) => { @@ -403,39 +394,59 @@ app.handle('search__intent__resume_listening_player', (conv) => { conv.scene.next.name = "search"; }); -app.handle('select_pub_after_search', (conv) => { +app.handle('select_publication', async (conv) => { + - conv.add('homeMembers.selection.publication'); + const url = conv.session.params.pubListUrl; + ok(isValidHttpUrl(url)); + await listPublication(url, conv); // wait intent }); -app.handle('select_pub_after_search__intent__stop', (conv) => { +app.handle('select_publication__intent__stop', (conv) => { conv.scene.next.name = 'home_members_lvl2'; }); -app.handle('select_pub_after_search__intent__resume_listening_player', (conv) => { +app.handle('select_publication__intent__resume_listening_player', (conv) => { - conv.scene.next.name = "select_pub_after_search"; + conv.scene.next.name = "select_publication"; }); -app.handle('select_pub_after_search__slot__number', async (conv) => { +app.handle('select_publication__intent__next', async (conv) => { + + const url = conv.session.params.pubListUrl; + ok(isValidHttpUrl(url)); + const nextUrl = await getNextLinkFromPublicationsFeed(url); + if (nextUrl && await isPublicationAvailable(nextUrl)) { + conv.session.params.pubListUrl = nextUrl; + conv.session.params.nextUrlCounter++; + } else { + conv.add('homeMembers.selection.noNext'); + } + + conv.scene.next.name = "select_publication"; +}); + +app.handle('select_publication__slot__number', async (conv) => { console.log('select_publication_number START'); const number = conv.intent.params?.number.resolved; console.log('NUMBER: ', number); - const query = conv.session.params.query; - ok(typeof query === 'string', 'error.noQuery'); - const url = SEARCH_URL.replace('{query}', encodeURIComponent(query)); - console.log('select_pub_after_search__slot__number URL: ', url); + const url = conv.session.params.pubListUrl; await selectPublication(url, number, conv); console.log('select_publication_number END'); }); +app.handle('select_publication__intent__repeat', async (conv) => { + + conv.scene.next.name = 'select_publication'; +}); + app.handle("player", async (conv) => { const url = conv.user.params.player.current.url; diff --git a/webhooks/functions/src/model/storage.dto.ts b/webhooks/functions/src/model/storage.dto.ts index de8f5a17..9a811f89 100644 --- a/webhooks/functions/src/model/storage.dto.ts +++ b/webhooks/functions/src/model/storage.dto.ts @@ -1,5 +1,5 @@ import * as util from 'util'; -import {IStorage, IStoragePlayer, IStoragePlayerCurrent, IStoragePlayerHistory, IStorageSelection} from './storage.interface'; +import {IStorage, IStoragePlayer, IStoragePlayerCurrent, IStoragePlayerHistory} from './storage.interface'; import {classToPlain, Exclude, plainToClass, Transform, TransformationType, Type} from 'class-transformer'; import {Equals, IsBoolean, IsDate, IsNotEmpty, IsNumber, IsObject, IsOptional, IsString, IsUrl, Min, ValidateNested, validateSync} from 'class-validator'; @@ -83,16 +83,6 @@ class StoragePlayerDto implements IStoragePlayer { } } -class StorageSelectionDto implements IStorageSelection { - @IsOptional() - @IsUrl() - topUrl?: string; - - @IsOptional() - @IsUrl() - url?: string; -} - export class StorageDto implements IStorage { @IsNumber() @Equals(DB_VERSION) @@ -107,12 +97,6 @@ export class StorageDto implements IStorage { @ValidateNested() player: StoragePlayerDto; - @IsObject() - @IsNotEmpty() - @Type(() => StorageSelectionDto) - @ValidateNested() - selection: StorageSelectionDto; - @Exclude() snapshot: IStorage; @@ -121,7 +105,6 @@ export class StorageDto implements IStorage { this.bearerToken = bearerToken; this.player = new StoragePlayerDto(); this.snapshot = classToPlain(this) as IStorage; - this.selection = new StorageSelectionDto(); } @Exclude() diff --git a/webhooks/functions/src/model/storage.interface.ts b/webhooks/functions/src/model/storage.interface.ts index f75e5276..561d489b 100644 --- a/webhooks/functions/src/model/storage.interface.ts +++ b/webhooks/functions/src/model/storage.interface.ts @@ -17,14 +17,8 @@ export interface IStoragePlayer { history: Map; } -export interface IStorageSelection { - topUrl?: string; - url?: string; -} - export interface IStorage { bearerToken: string; - selection: IStorageSelection; player: IStoragePlayer; } diff --git a/webhooks/functions/src/model/storage.test.ts b/webhooks/functions/src/model/storage.test.ts index 6db09b82..fc8da27a 100644 --- a/webhooks/functions/src/model/storage.test.ts +++ b/webhooks/functions/src/model/storage.test.ts @@ -18,7 +18,6 @@ describe('storage DTO', () => { }, }, - selection: {}, }; assert.throws(() => StorageDto.create(obj)); @@ -37,7 +36,6 @@ describe('storage DTO', () => { }, }, - selection: {}, }; const instance = StorageDto.create(obj); @@ -59,7 +57,6 @@ describe('storage DTO', () => { history: { }, - selection: {}, }, }; @@ -83,7 +80,6 @@ describe('storage DTO', () => { }, }, - selection: {}, }, extr); }); @@ -106,43 +102,42 @@ describe('storage DTO', () => { }, }, - // selection: {} }, extr); - const instance2 = StorageDto.create(extr); + // const instance2 = StorageDto.create(extr); - assert.deepEqual(instance2.selection, {}); - assert.deepEqual(instance2.selection.url, undefined); + // assert.deepEqual(instance2.selection, {}); + // assert.deepEqual(instance2.selection.url, undefined); }); - it('selection validation extract', () => { - const instance = StorageDto.create(undefined, 'test'); + // it('selection validation extract', () => { + // const instance = StorageDto.create(undefined, 'test'); - instance.selection.url = undefined; - // instance.selection.topUrl = "http://google.com"; + // instance.selection.url = undefined; + // // instance.selection.topUrl = "http://google.com"; - const extr = instance.extract(); + // const extr = instance.extract(); - assert.deepEqual({ - dbVersion: 1, - bearerToken: 'test', - player: { - current: { + // assert.deepEqual({ + // dbVersion: 1, + // bearerToken: 'test', + // player: { + // current: { - playing: false, - }, - history: { + // playing: false, + // }, + // history: { - }, - }, - selection: {}, - }, extr); + // }, + // }, + // selection: {}, + // }, extr); - const instance2 = StorageDto.create(extr); + // const instance2 = StorageDto.create(extr); - assert.deepEqual(instance2.selection, {}); - assert.deepEqual(instance2.selection.url, undefined); - }); + // assert.deepEqual(instance2.selection, {}); + // assert.deepEqual(instance2.selection.url, undefined); + // }); it('good validation extract', () => { const instance = StorageDto.create(undefined, 'test'); @@ -163,7 +158,6 @@ describe('storage DTO', () => { }, }, - selection: {}, }, extr); }); @@ -186,7 +180,6 @@ describe('storage DTO', () => { }, }, }, - selection: {}, }; const instance = StorageDto.create(obj, 'test'); @@ -225,7 +218,6 @@ describe('storage DTO', () => { }, }, }, - selection: {}, }, extr); console.log(inspect(extr, {depth: 7})); diff --git a/webhooks/functions/src/sdk.d.ts b/webhooks/functions/src/sdk.d.ts index ae535c9e..74f490d9 100644 --- a/webhooks/functions/src/sdk.d.ts +++ b/webhooks/functions/src/sdk.d.ts @@ -1,4 +1,4 @@ -// npm run typed:scene ; +// npm run scene-typed ; -export type TSdkScene = 'ask_to_resume_listening_at_last_offset' | 'home_lvl1' | 'home_lvl1_AccountLinking' | 'home_members_lvl2' | 'player' | 'search' | 'select_list_after_list_selection' | 'select_pub_after_search' | 'select_pub_after_selection' | 'selection_lvl3'; +export type TSdkScene = 'ask_to_resume_listening_at_last_offset' | 'home_lvl1' | 'home_lvl1_AccountLinking' | 'home_members_lvl2' | 'player' | 'search' | 'select_group' | 'select_publication' | 'selection_lvl3'; diff --git a/webhooks/functions/src/service/listGroups.ts b/webhooks/functions/src/service/listGroups.ts index d535156f..24d6d332 100644 --- a/webhooks/functions/src/service/listGroups.ts +++ b/webhooks/functions/src/service/listGroups.ts @@ -4,24 +4,25 @@ import {getGroupsFromFeed, isValidHttpUrl} from '../utils'; import {ok} from 'assert'; import {t} from '../translation'; -export async function listGroups(url: string, conv: IConversationWithParams, nextScene: TSdkScene, errorScene: TSdkScene = conv.scene.name) { +export async function listGroups(url: string, conv: IConversationWithParams, errorScene: TSdkScene = conv.scene.name) { ok(isValidHttpUrl(url), 'url not valid'); const list = await getGroupsFromFeed(url); console.log('SELECTIONS: ', list); const length = list.length; if (length > 1) { - conv.scene.next.name = nextScene; - conv.add('homeMembers.list.numberPublication', {length}); - - let text = ''; + let text = t('homeMembers.list.numberSelection', {length}); list.map(({title}, i) => { text += t('homeMembers.list.numero', {i: i + 1, title}); }); + + text += '\n'; + text += t('homeMembers.selection.listAfterSelection'); + conv.add('free', {text}); } else if (length === 1) { - conv.scene.next.name = 'select_pub_after_selection'; - conv.user.params.selection.url = list[0].groupUrl; + conv.scene.next.name = 'select_publication'; + conv.session.params.pubListUrl = list[0].groupUrl; } else { conv.scene.next.name = errorScene; conv.add('homeMembers.list.noResult'); diff --git a/webhooks/functions/src/service/listPublication.ts b/webhooks/functions/src/service/listPublication.ts index 697aae62..cb5078c3 100644 --- a/webhooks/functions/src/service/listPublication.ts +++ b/webhooks/functions/src/service/listPublication.ts @@ -1,24 +1,34 @@ import {TSdkScene} from '../sdk'; import {IConversationWithParams} from '../type'; -import {getPubsFromFeed, isValidHttpUrl} from '../utils'; +import {getNextLinkFromPublicationsFeed, getPubsFromFeed, isPublicationAvailable, isValidHttpUrl} from '../utils'; import {ok} from 'assert'; import {t} from '../translation'; -export async function listPublication(url: string, conv: IConversationWithParams, nextScene: TSdkScene, errorScene: TSdkScene = conv.scene.name) { +export async function listPublication(url: string, conv: IConversationWithParams, + errorScene: TSdkScene = conv.session?.params?.scene) { ok(isValidHttpUrl(url), 'url not valid'); const list = await getPubsFromFeed(url); + const nextUrl = await getNextLinkFromPublicationsFeed(url); console.log('PUBs: ', list); const length = list.length; - if (length > 1) { - conv.scene.next.name = nextScene; - conv.add('homeMembers.list.numberPublication', {length}); + if (length > 1 || conv.session.params.nextUrlCounter) { + const page = conv.session.params.nextUrlCounter + 1; + let text = t('homeMembers.list.numberPublication', {length}) + '\n'; + if (nextUrl && await isPublicationAvailable(nextUrl)) { + text += t('homeMembers.list.pagePublication', {page}) + '\n'; + } + + list + .slice(0, 5) + .map(({title, author}, i) => { + text += t('homeMembers.list.numeroWithAuthor', + {i: i + 1, title, author: author ? t('homeMembers.list.numeroWithAuthorOf', {author}) : ''}); + }); + + text += '\n'; + text += t('homeMembers.selection.publication'); - let text = ''; - list.map(({title, author}, i) => { - text += t('homeMembers.list.numeroWithAuthor', - {i: i + 1, title, author: author ? t('homeMembers.list.numeroWithAuthorOf', {author}) : ''}); - }); conv.add('free', {text}); } else if (length === 1) { conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; diff --git a/webhooks/functions/src/service/selectGroups.ts b/webhooks/functions/src/service/selectGroups.ts index 5671b17d..2f37a1cd 100644 --- a/webhooks/functions/src/service/selectGroups.ts +++ b/webhooks/functions/src/service/selectGroups.ts @@ -11,11 +11,11 @@ export async function selectGroup(url: string, number: number, conv: IConversati conv.add('homeMembers.list.wrongNumber', {number}); conv.scene.next.name = conv.scene.name; // loop selection or search - return; + return undefined; } console.log('Groups: ', group); - conv.user.params.selection.url = group.groupUrl; + return group.groupUrl; // conv.scene.next.name = 'select_pub_after_selection'; } diff --git a/webhooks/functions/src/translation/fr/fr.json b/webhooks/functions/src/translation/fr/fr.json index 09efb241..1824a353 100644 --- a/webhooks/functions/src/translation/fr/fr.json +++ b/webhooks/functions/src/translation/fr/fr.json @@ -25,16 +25,21 @@ }, "selection": { "welcome": "Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre. Que voulez-vous faire ?", - "publication": "Pour choisir une publication, dites son numéro.", + "publication": "Pour choisir l'une des publications, dites son numéro.", + "next": "Pour obtenir la suite, dites suivant.", + "noNext": "Il n'y a pas de page suivante, dites répéter pour recommencer", "listAfterSelection": "Pour choisir une sélection, dites son numéro." }, "list": { "wrongNumber": "Le numéro {{number}} est inconnu. Veuillez choisir un autre numéro.", - "numberPublication": "J'ai trouvé {{length}} publications.\n", + "numberSelection": "J'ai trouvé {{length}} sélections.\n", + "numberPublication": "J'ai trouvé {{length}} publications.", + "pagePublication": "Vous êtes sur la page {{page}}.", "numero": "numéro {{i}} : {{- title}}.\n", "numeroWithAuthor": "numéro {{i}} : {{- title}} {{- author}}.\n", "numeroWithAuthorOf": "de {{- author}}", - "noResult": "Aucun résultat trouvé." + "noResult": "Aucun résultat trouvé.", + "repeat": "dite répéter pour recommencer" }, "search": "Que voulez-vous écouter ? Par exemple Zola." }, @@ -54,4 +59,4 @@ "webhook": "webhook work: {{- message}}" }, "free": "{{- text}}" -} \ No newline at end of file +} diff --git a/webhooks/functions/src/type.ts b/webhooks/functions/src/type.ts index 9e3a875f..7a925394 100644 --- a/webhooks/functions/src/type.ts +++ b/webhooks/functions/src/type.ts @@ -34,7 +34,11 @@ export interface IConversationWithParams extends ConversationV3 { add: (...promptItems: TPromptItem[]) => this; session: { params: { - [key: string]: any; + pubListUrl: string; + groupListUrl: string; + query: string; + scene: TSdkScene; + nextUrlCounter: number; } } } \ No newline at end of file diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index 9c138110..8eed58a3 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,9 +3,9 @@ export interface Translations { keys: { - "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberPublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.search" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "test.player" | "test.setupSdk" | "test.webhook" | "free" + "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.search" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" + "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } diff --git a/webhooks/functions/src/utils/index.ts b/webhooks/functions/src/utils/index.ts index bbf1bcad..0dc2b8ce 100644 --- a/webhooks/functions/src/utils/index.ts +++ b/webhooks/functions/src/utils/index.ts @@ -28,7 +28,6 @@ export async function getPubsFromFeed(url: string) { isValidHttpUrl(l[0].url) ); }) - .slice(0, 5) .map(({title, authors, openAccessLinks}) => ({ title: title, author: Array.isArray(authors) ? authors[0].name : '', @@ -56,3 +55,28 @@ export async function getGroupsFromFeed(url: string) { return list; } +export async function isPublicationAvailable(url: string): Promise { + assert.ok(isValidHttpUrl(url)); + const pubs = await getPubsFromFeed(url); + + if (pubs.length) { + return true; + } + return false; +} + +export async function getNextLinkFromPublicationsFeed(url: string): Promise { + assert.ok(isValidHttpUrl(url)); + const opds = new OpdsFetcher(); + const feed = await opds.feedRequest(url); + + try { + const nextLink = feed.links?.next[0].url; + if (nextLink && await isPublicationAvailable(nextLink)) { + return nextLink; + } else { + } + } catch { + } + return undefined; +} From 7823d31d064afbd0a38fa3f3e8c18841445b398f Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Fri, 17 Dec 2021 16:07:30 +0100 Subject: [PATCH 049/180] fix: next feature --- .../functions/src/service/listPublication.ts | 16 ++++++------- .../src/service/selectPublication.ts | 2 +- webhooks/functions/src/utils/index.ts | 23 ++++++++++++++++--- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/webhooks/functions/src/service/listPublication.ts b/webhooks/functions/src/service/listPublication.ts index cb5078c3..07d539d8 100644 --- a/webhooks/functions/src/service/listPublication.ts +++ b/webhooks/functions/src/service/listPublication.ts @@ -7,24 +7,22 @@ import {t} from '../translation'; export async function listPublication(url: string, conv: IConversationWithParams, errorScene: TSdkScene = conv.session?.params?.scene) { ok(isValidHttpUrl(url), 'url not valid'); - const list = await getPubsFromFeed(url); + const [list, totalLength] = await getPubsFromFeed(url); const nextUrl = await getNextLinkFromPublicationsFeed(url); console.log('PUBs: ', list); const length = list.length; if (length > 1 || conv.session.params.nextUrlCounter) { const page = conv.session.params.nextUrlCounter + 1; - let text = t('homeMembers.list.numberPublication', {length}) + '\n'; - if (nextUrl && await isPublicationAvailable(nextUrl)) { + let text = t('homeMembers.list.numberPublication', {length: totalLength}) + '\n'; + if (page > 1 || nextUrl && await isPublicationAvailable(nextUrl)) { text += t('homeMembers.list.pagePublication', {page}) + '\n'; } - list - .slice(0, 5) - .map(({title, author}, i) => { - text += t('homeMembers.list.numeroWithAuthor', - {i: i + 1, title, author: author ? t('homeMembers.list.numeroWithAuthorOf', {author}) : ''}); - }); + list.map(({title, author}, i) => { + text += t('homeMembers.list.numeroWithAuthor', + {i: i + 1, title, author: author ? t('homeMembers.list.numeroWithAuthorOf', {author}) : ''}); + }); text += '\n'; text += t('homeMembers.selection.publication'); diff --git a/webhooks/functions/src/service/selectPublication.ts b/webhooks/functions/src/service/selectPublication.ts index c317ae2b..7a465f54 100644 --- a/webhooks/functions/src/service/selectPublication.ts +++ b/webhooks/functions/src/service/selectPublication.ts @@ -4,7 +4,7 @@ import {getPubsFromFeed, isValidHttpUrl} from '../utils'; export async function selectPublication(url: string, number: number, conv: IConversationWithParams) { ok(isValidHttpUrl(url), 'error.urlNotValid'); - const list = await getPubsFromFeed(url); + const [list] = await getPubsFromFeed(url); const pub = list[number - 1]; if (!pub) { console.log('NO PUBS found !!'); diff --git a/webhooks/functions/src/utils/index.ts b/webhooks/functions/src/utils/index.ts index 0dc2b8ce..f62e995c 100644 --- a/webhooks/functions/src/utils/index.ts +++ b/webhooks/functions/src/utils/index.ts @@ -15,7 +15,11 @@ export function isValidHttpUrl(url: string | undefined): url is string { return _url.protocol === 'http:' || _url.protocol === 'https:'; } -export async function getPubsFromFeed(url: string) { +export async function getPubsFromFeed(url: string): Promise<[{ + title: string; + author: string; + webpuburl: string; +}[], number]> { const opds = new OpdsFetcher(); const feed = await opds.feedRequest(url); @@ -28,13 +32,26 @@ export async function getPubsFromFeed(url: string) { isValidHttpUrl(l[0].url) ); }) + .slice(0, 5) .map(({title, authors, openAccessLinks}) => ({ title: title, author: Array.isArray(authors) ? authors[0].name : '', webpuburl: (openAccessLinks as IOpdsLinkView[])[0].url, })); - return list; + console.log('%%%%%%%%%%%%%%'); + console.log('%%%%%%%%%%%%%%'); + console.log('%%%%%%%%%%%%%%'); + console.log('%%%%%%%%%%%%%%'); + + console.log(feed.metadata?.numberOfItems); + + console.log('%%%%%%%%%%%%%%'); + console.log('%%%%%%%%%%%%%%'); + console.log('%%%%%%%%%%%%%%'); + console.log('%%%%%%%%%%%%%%'); + + return [list, feed.metadata?.numberOfItems || list.length]; } export async function getGroupsFromFeed(url: string) { @@ -57,7 +74,7 @@ export async function getGroupsFromFeed(url: string) { export async function isPublicationAvailable(url: string): Promise { assert.ok(isValidHttpUrl(url)); - const pubs = await getPubsFromFeed(url); + const [pubs] = await getPubsFromFeed(url); if (pubs.length) { return true; From 20f7e9e5a54691fc002e51c200cc38defcccd5f6 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Fri, 17 Dec 2021 17:15:08 +0100 Subject: [PATCH 050/180] fix: next feature with Laurent --- webhooks/functions/src/index.ts | 2 +- webhooks/functions/src/service/listPublication.ts | 11 ++++++++--- webhooks/functions/src/translation/fr/fr.json | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index cf7fb4d4..ed02d993 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -423,7 +423,7 @@ app.handle('select_publication__intent__next', async (conv) => { conv.session.params.pubListUrl = nextUrl; conv.session.params.nextUrlCounter++; } else { - conv.add('homeMembers.selection.noNext'); + conv.add('homeMembers.selection.noNext') + '\n'; } conv.scene.next.name = "select_publication"; diff --git a/webhooks/functions/src/service/listPublication.ts b/webhooks/functions/src/service/listPublication.ts index 07d539d8..0a36dad6 100644 --- a/webhooks/functions/src/service/listPublication.ts +++ b/webhooks/functions/src/service/listPublication.ts @@ -14,9 +14,12 @@ export async function listPublication(url: string, conv: IConversationWithParams const length = list.length; if (length > 1 || conv.session.params.nextUrlCounter) { const page = conv.session.params.nextUrlCounter + 1; - let text = t('homeMembers.list.numberPublication', {length: totalLength}) + '\n'; - if (page > 1 || nextUrl && await isPublicationAvailable(nextUrl)) { + const nextAvailable = !!nextUrl && await isPublicationAvailable(nextUrl); + let text = ""; + if (page > 1 || nextAvailable) { text += t('homeMembers.list.pagePublication', {page}) + '\n'; + } else { + text += t('homeMembers.list.numberPublication', {length: totalLength}) + '\n'; } list.map(({title, author}, i) => { @@ -25,7 +28,9 @@ export async function listPublication(url: string, conv: IConversationWithParams }); text += '\n'; - text += t('homeMembers.selection.publication'); + text += t('homeMembers.selection.publication') + '\n'; + if (nextAvailable) + text += t('homeMembers.selection.next'); conv.add('free', {text}); } else if (length === 1) { diff --git a/webhooks/functions/src/translation/fr/fr.json b/webhooks/functions/src/translation/fr/fr.json index 1824a353..212aa650 100644 --- a/webhooks/functions/src/translation/fr/fr.json +++ b/webhooks/functions/src/translation/fr/fr.json @@ -27,7 +27,7 @@ "welcome": "Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre. Que voulez-vous faire ?", "publication": "Pour choisir l'une des publications, dites son numéro.", "next": "Pour obtenir la suite, dites suivant.", - "noNext": "Il n'y a pas de page suivante, dites répéter pour recommencer", + "noNext": "Il n'y a pas de page suivante, je vais répéter la dernière page.", "listAfterSelection": "Pour choisir une sélection, dites son numéro." }, "list": { From d1c84d1e72d1689a1323bda1939928dc03a9d9dd Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Fri, 17 Dec 2021 17:56:50 +0100 Subject: [PATCH 051/180] lint --- webhooks/functions/src/service/listPublication.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/webhooks/functions/src/service/listPublication.ts b/webhooks/functions/src/service/listPublication.ts index 0a36dad6..101937a6 100644 --- a/webhooks/functions/src/service/listPublication.ts +++ b/webhooks/functions/src/service/listPublication.ts @@ -15,7 +15,7 @@ export async function listPublication(url: string, conv: IConversationWithParams if (length > 1 || conv.session.params.nextUrlCounter) { const page = conv.session.params.nextUrlCounter + 1; const nextAvailable = !!nextUrl && await isPublicationAvailable(nextUrl); - let text = ""; + let text = ''; if (page > 1 || nextAvailable) { text += t('homeMembers.list.pagePublication', {page}) + '\n'; } else { @@ -29,8 +29,9 @@ export async function listPublication(url: string, conv: IConversationWithParams text += '\n'; text += t('homeMembers.selection.publication') + '\n'; - if (nextAvailable) + if (nextAvailable) { text += t('homeMembers.selection.next'); + } conv.add('free', {text}); } else if (length === 1) { From 7a329898369f8c5b976416738a4f3bac274bc939 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Fri, 17 Dec 2021 18:14:16 +0100 Subject: [PATCH 052/180] fix: next feature --- webhooks/functions/src/service/listPublication.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/webhooks/functions/src/service/listPublication.ts b/webhooks/functions/src/service/listPublication.ts index 101937a6..bc376fa6 100644 --- a/webhooks/functions/src/service/listPublication.ts +++ b/webhooks/functions/src/service/listPublication.ts @@ -19,7 +19,8 @@ export async function listPublication(url: string, conv: IConversationWithParams if (page > 1 || nextAvailable) { text += t('homeMembers.list.pagePublication', {page}) + '\n'; } else { - text += t('homeMembers.list.numberPublication', {length: totalLength}) + '\n'; + if (page === 1) + text += t('homeMembers.list.numberPublication', { length: totalLength }) + '\n'; } list.map(({title, author}, i) => { From 91b778eda9a2e75b8c55f174f51789c3f1e067a3 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Fri, 17 Dec 2021 18:18:13 +0100 Subject: [PATCH 053/180] lint --- webhooks/functions/src/service/listPublication.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/webhooks/functions/src/service/listPublication.ts b/webhooks/functions/src/service/listPublication.ts index bc376fa6..9d93c02d 100644 --- a/webhooks/functions/src/service/listPublication.ts +++ b/webhooks/functions/src/service/listPublication.ts @@ -19,8 +19,9 @@ export async function listPublication(url: string, conv: IConversationWithParams if (page > 1 || nextAvailable) { text += t('homeMembers.list.pagePublication', {page}) + '\n'; } else { - if (page === 1) - text += t('homeMembers.list.numberPublication', { length: totalLength }) + '\n'; + if (page === 1) { + text += t('homeMembers.list.numberPublication', {length: totalLength}) + '\n'; + } } list.map(({title, author}, i) => { From 46a23db325c893c04c7eee9c51fb1864a8dbfcb3 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Fri, 17 Dec 2021 18:49:05 +0100 Subject: [PATCH 054/180] fix: listPublications --- webhooks/functions/src/service/listPublication.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/webhooks/functions/src/service/listPublication.ts b/webhooks/functions/src/service/listPublication.ts index 9d93c02d..5f0d3edc 100644 --- a/webhooks/functions/src/service/listPublication.ts +++ b/webhooks/functions/src/service/listPublication.ts @@ -16,12 +16,11 @@ export async function listPublication(url: string, conv: IConversationWithParams const page = conv.session.params.nextUrlCounter + 1; const nextAvailable = !!nextUrl && await isPublicationAvailable(nextUrl); let text = ''; + if (page === 1) { + text += t('homeMembers.list.numberPublication', {length: totalLength}) + '\n'; + } if (page > 1 || nextAvailable) { text += t('homeMembers.list.pagePublication', {page}) + '\n'; - } else { - if (page === 1) { - text += t('homeMembers.list.numberPublication', {length: totalLength}) + '\n'; - } } list.map(({title, author}, i) => { From 902d7653f8c0844a38fac2625015d7fd0271eaeb Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Fri, 17 Dec 2021 19:24:02 +0100 Subject: [PATCH 055/180] fix: menu intent in select_group --- sdk/test/custom/scenes/select_group.yaml | 3 +++ sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml | 1 + webhooks/functions/src/index.ts | 5 +++++ 3 files changed, 9 insertions(+) diff --git a/sdk/test/custom/scenes/select_group.yaml b/sdk/test/custom/scenes/select_group.yaml index bca991f5..203b7eb2 100644 --- a/sdk/test/custom/scenes/select_group.yaml +++ b/sdk/test/custom/scenes/select_group.yaml @@ -2,6 +2,9 @@ intentEvents: - handler: webhookHandler: select_group__intent__stop intent: stop +- handler: + webhookHandler: select_group__intent__menu + intent: menu - handler: staticPrompt: candidates: diff --git a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml index dba81c2c..bc02c429 100644 --- a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml @@ -39,6 +39,7 @@ handlers: - name: select_group__intent__stop - name: selection_lvl3__intent__selection_all_publication_lvl3 - name: select_publication__intent__repeat +- name: select_group__intent__menu httpsEndpoint: baseUrl: https://us-central1-valentin-5.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index ed02d993..29e9622b 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -297,6 +297,11 @@ app.handle('select_group__intent__stop', (conv) => { conv.scene.next.name = 'home_members_lvl2'; }); +app.handle('select_group__intent__menu', (conv) => { + + conv.scene.next.name = 'home_members_lvl2'; +}); + app.handle('select_group__slot__number', async (conv) => { console.log('select_group_number START'); From ca2a0b03fd3ec8f9fb8e85ffad9f9422455de8c6 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Fri, 17 Dec 2021 19:49:13 +0100 Subject: [PATCH 056/180] test --- test/dev/test/test2.ts | 2 +- test/dev/test/test3-2.ts | 74 ++++++++++++++++++++++++++++++++++++++++ test/dev/test/test3.ts | 4 +-- 3 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 test/dev/test/test3-2.ts diff --git a/test/dev/test/test2.ts b/test/dev/test/test2.ts index d6e2dfc7..68eb2dcc 100644 --- a/test/dev/test/test2.ts +++ b/test/dev/test/test2.ts @@ -31,7 +31,7 @@ describe('My Action Test Suite', function () { await test.sendQuery('test avec aucune publication renvoyées'); - await test.assertSpeech(`aucun résultat trouvé Que voulez-vous écouter ? Par exemple Zola.`); + await test.assertSpeech(`Aucun résultat trouvé. Que voulez-vous écouter ? Par exemple Zola.`); // // resp = test.getLatestResponse(); diff --git a/test/dev/test/test3-2.ts b/test/dev/test/test3-2.ts new file mode 100644 index 00000000..a36d4818 --- /dev/null +++ b/test/dev/test/test3-2.ts @@ -0,0 +1,74 @@ +import 'mocha'; + +import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; +import {ok} from 'assert'; +import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; + +const TEST_NUM = 302; + +describe('My Action Test Suite', function () { + // Set the timeout for each test run to 60s. + this.timeout(60000); + let test: ActionsOnGoogleTestManager; + + async function startConversation() { + await test.sendQuery(TRIGGER_PHRASE); + test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); + // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); + test.assertIntent('actions.intent.MAIN'); + test.assertScene('home_members_lvl2'); + + await test.sendQuery(`setup test ${TEST_NUM}`); + + test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); + + // RECHERCHE + + await test.sendQuery('recherche'); + + test.assertSpeech(`Que voulez-vous écouter ?`); + + await test.sendQuery('*'); + + test.assertSpeech(`J'ai trouvé 8 publications.\nVous êtes sur la page 1.\nnuméro 1 : vingt mille lieu sous les mers de Jule Verne.\nnuméro 2 : La chevre de monsieur segin de Alphonse Daudet.\nnuméro 3 : peau d'âne de Charles Perrault.\nnuméro 4 : Thérèse Raquin de Emile Zola.\nnuméro 5 : Du contrat social de Rousseau.\n\nPour choisir l'une des publications, dites son numéro.`); + + await test.sendQuery('0'); + + test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. J'ai trouvé 8 publications.\nVous êtes sur la page 1.\nnuméro 1 : vingt mille lieu sous les mers de Jule Verne.\nnuméro 2 : La chevre de monsieur segin de Alphonse Daudet.\nnuméro 3 : peau d'âne de Charles Perrault.\nnuméro 4 : Thérèse Raquin de Emile Zola.\nnuméro 5 : Du contrat social de Rousseau.\n\nPour choisir l'une des publications, dites son numéro.`); + + await test.sendQuery('suivant'); + + test.assertSpeech("Vous êtes sur la page 2.\nnuméro 1 : la guerre des boutons de pergaud.\nnuméro 2 : le prince de Nicolas Machiavel.\nnuméro 3 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n"); + + await test.sendQuery('suivant'); + + test.assertSpeech("Il n'y a pas de page suivante, je vais répéter la dernière page. Vous êtes sur la page 2.\nnuméro 1 : la guerre des boutons de pergaud.\nnuméro 2 : le prince de Nicolas Machiavel.\nnuméro 3 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n"); + + await test.sendQuery('repete'); + + test.assertSpeech("Vous êtes sur la page 2.\nnuméro 1 : la guerre des boutons de pergaud.\nnuméro 2 : le prince de Nicolas Machiavel.\nnuméro 3 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n"); + + test.assertScene('select_publication'); + + // + // resp = test.getLatestResponse(); + } + + before('before all', async () => { + // Load project settings to read project ID and trigger phrase. + test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); + await test.writePreviewFromDraft(); + test.setSuiteLocale(DEFAULT_LOCALE); + test.setSuiteSurface(DEFAULT_SURFACE); + }); + + afterEach('post test cleans', async () => { + test.cleanUpAfterTest(); + }); + + it('search with zola query', async () => { + await startConversation(); + await test.sendQuery("quitter"); + // test.assertConversationEnded(); + }); +}); diff --git a/test/dev/test/test3.ts b/test/dev/test/test3.ts index 704e9d54..65cf320b 100644 --- a/test/dev/test/test3.ts +++ b/test/dev/test/test3.ts @@ -31,13 +31,13 @@ describe('My Action Test Suite', function () { await test.sendQuery('zola'); - await test.assertSpeech(`J'ai trouvé 2 publications.\n Pour choisir une publication, dites son numéro.numéro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n`); + await test.assertSpeech(`J'ai trouvé 2 publications.\nnuméro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n`); await test.sendQuery('0'); await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. Pour choisir une publication, dites son numéro.`); - test.assertScene('select_pub_after_search'); + test.assertScene('select_publication'); // // resp = test.getLatestResponse(); From 07743ebaa15b2b6a99307cc08aa01053564e75d7 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 20 Dec 2021 00:06:56 +0100 Subject: [PATCH 057/180] Update sdk-test-dev.yml --- .github/workflows/sdk-test-dev.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/sdk-test-dev.yml b/.github/workflows/sdk-test-dev.yml index 8c2c9fae..5b8491b0 100644 --- a/.github/workflows/sdk-test-dev.yml +++ b/.github/workflows/sdk-test-dev.yml @@ -9,6 +9,7 @@ on: # branches: [ develop ] paths: - 'sdk/test/**' + - 'test/dev/**' - '.github/workflows/sdk-test-dev.yml' jobs: From e46c39746cd2b2b8d946ef72f0e5a3b7a66de623 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 20 Dec 2021 13:39:04 +0100 Subject: [PATCH 058/180] fix: test --- test/dev/test/test12.ts | 6 +++--- test/dev/test/test3.ts | 2 +- test/dev/test/test4.ts | 6 +++--- test/dev/test/test9.ts | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/dev/test/test12.ts b/test/dev/test/test12.ts index 2bd583ad..f627359d 100644 --- a/test/dev/test/test12.ts +++ b/test/dev/test/test12.ts @@ -33,13 +33,13 @@ describe('My Action Test Suite', function () { await test.sendQuery('zola'); - await test.assertSpeech(`J'ai trouvé 2 publications.\n Pour choisir une publication, dites son numéro.numéro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n`); + await test.assertSpeech(`J'ai trouvé 2 publications.\nnuméro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n`); await test.sendQuery('0'); - await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. Pour choisir une publication, dites son numéro.`); + await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. J'ai trouvé 2 publications.\nnuméro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n`); - test.assertScene('select_pub_after_search'); + test.assertScene('select_publication'); await test.sendQuery('revenir au menu principal'); diff --git a/test/dev/test/test3.ts b/test/dev/test/test3.ts index 65cf320b..720aacec 100644 --- a/test/dev/test/test3.ts +++ b/test/dev/test/test3.ts @@ -35,7 +35,7 @@ describe('My Action Test Suite', function () { await test.sendQuery('0'); - await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. Pour choisir une publication, dites son numéro.`); + await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. J'ai trouvé 2 publications.\nnuméro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n`); test.assertScene('select_publication'); diff --git a/test/dev/test/test4.ts b/test/dev/test/test4.ts index 51e1ee6e..1424aa0d 100644 --- a/test/dev/test/test4.ts +++ b/test/dev/test/test4.ts @@ -33,13 +33,13 @@ describe('My Action Test Suite', function () { await test.sendQuery('zola'); - await test.assertSpeech(`J'ai trouvé 2 publications.\n Pour choisir une publication, dites son numéro.numéro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n`); + await test.assertSpeech(`J'ai trouvé 2 publications.\nnuméro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n`); await test.sendQuery('0'); - await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. Pour choisir une publication, dites son numéro.`); + await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. J'ai trouvé 2 publications.\nnuméro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n`); - test.assertScene('select_pub_after_search'); + test.assertScene('select_publication'); await test.sendQuery('1'); diff --git a/test/dev/test/test9.ts b/test/dev/test/test9.ts index c62fba1d..f5fbed22 100644 --- a/test/dev/test/test9.ts +++ b/test/dev/test/test9.ts @@ -29,7 +29,7 @@ describe('My Action Test Suite', function () { test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre. Que voulez-vous faire ?`); await test.sendQuery(`ma liste`); - test.assertSpeech(`J'ai trouvé 2 publications.\n Pour choisir une publication, dites son numéro.numéro 1 : L'assommoir de Emile Zola\nnuméro 2 : Du contrat social de Rousseau\n`); + test.assertSpeech(`numéro 1 : L'assommoir de Emile Zola.\nnuméro 2 : Du contrat social de Rousseau.\n\nPour choisir l'une des publications, dites son numéro.\n`); await test.sendQuery(`2`); From 5a2838d0f4682e48339c006c9abd1ccda795e64d Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 20 Dec 2021 14:32:57 +0100 Subject: [PATCH 059/180] first toc --- sdk/test/custom/scenes/player.yaml | 5 +- sdk/test/custom/scenes/player_toc.yaml | 19 ++++++++ .../webhooks/ActionsOnGoogleFulfillment.yaml | 6 ++- webhooks/functions/src/index.ts | 46 +++++++++++++++++++ webhooks/functions/src/sdk.d.ts | 2 +- webhooks/functions/src/translation/fr/fr.json | 3 +- webhooks/functions/src/typings/i18n.d.ts | 4 +- 7 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 sdk/test/custom/scenes/player_toc.yaml diff --git a/sdk/test/custom/scenes/player.yaml b/sdk/test/custom/scenes/player.yaml index 4f882dde..19a7b57c 100644 --- a/sdk/test/custom/scenes/player.yaml +++ b/sdk/test/custom/scenes/player.yaml @@ -5,9 +5,8 @@ intentEvents: - handler: webhookHandler: player__intent__remaining_time_player intent: remaing_time_player -- handler: - webhookHandler: player__intent__listen_toc - intent: listen_toc +- intent: listen_toc + transitionToScene: player_toc - handler: webhookHandler: player__intent__menu intent: menu diff --git a/sdk/test/custom/scenes/player_toc.yaml b/sdk/test/custom/scenes/player_toc.yaml new file mode 100644 index 00000000..7cfb9b62 --- /dev/null +++ b/sdk/test/custom/scenes/player_toc.yaml @@ -0,0 +1,19 @@ +intentEvents: +- handler: + webhookHandler: player_toc__intent__repeat + intent: repeat +- handler: + webhookHandler: player_toc__intent__next + intent: next +- handler: + webhookHandler: player_toc__intent__resume_listening_player + intent: resume_listening_player +onEnter: + webhookHandler: player_toc +onSlotUpdated: + webhookHandler: player_toc__slot__number +slots: +- name: number + required: true + type: + name: actions.type.Number diff --git a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml index bc02c429..04e88c57 100644 --- a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml @@ -27,7 +27,6 @@ handlers: - name: test_setup_sdk - name: test_webhook - name: ask_to_resume_listening_at_last_offset__intent__no -- name: player__intent__listen_toc - name: player__intent__menu - name: select_publication__slot__number - name: select_publication__intent__resume_listening_player @@ -40,6 +39,11 @@ handlers: - name: selection_lvl3__intent__selection_all_publication_lvl3 - name: select_publication__intent__repeat - name: select_group__intent__menu +- name: player_toc +- name: player_toc__intent__repeat +- name: player_toc__intent__next +- name: player_toc__intent__resume_listening_player +- name: player_toc__slot__number httpsEndpoint: baseUrl: https://us-central1-valentin-5.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 29e9622b..02094945 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -604,6 +604,52 @@ app.handle('player__intent__remaining_time_player', async (conv) => { conv.scene.next.name = 'player'; }); +app.handle('player_toc', async (conv) => { + persistMediaPlayer(conv); + + const url = conv.user.params.player.current.url; + + ok(isValidHttpUrl(url), 'error.urlNotValid'); + + const opds = new OpdsFetcher(); + const webpub = await opds.webpubRequest(url); + + if (!webpub?.toc) { + + conv.add('player.tocNotFound'); + return ; + } + + const toc = webpub.toc; + const title = toc.map(({title}) => title).filter((v) => v).slice(0, 5); + const text = title.join(".\n "); + + conv.add('free', { text }); + + conv.scene.next.name = "player"; +}); + +app.handle('player_toc__slot__number', (conv) => { + + + conv.scene.next.name = 'player'; +}); + +app.handle('player_toc__intent__next', (conv) => { + + conv.scene.next.name = 'player_toc'; +}); + +app.handle('player_toc__intent__repeat', (conv) => { + + conv.scene.next.name = 'player_toc'; +}); + +app.handle('player_toc__intent__resume_listening_player', (conv) => { + + conv.scene.next.name = 'player'; +}); + // //////////////////////// // Media PLAYET CONTEXT // // //////////////////////// diff --git a/webhooks/functions/src/sdk.d.ts b/webhooks/functions/src/sdk.d.ts index 74f490d9..2637b4a7 100644 --- a/webhooks/functions/src/sdk.d.ts +++ b/webhooks/functions/src/sdk.d.ts @@ -1,4 +1,4 @@ // npm run scene-typed ; -export type TSdkScene = 'ask_to_resume_listening_at_last_offset' | 'home_lvl1' | 'home_lvl1_AccountLinking' | 'home_members_lvl2' | 'player' | 'search' | 'select_group' | 'select_publication' | 'selection_lvl3'; +export type TSdkScene = 'ask_to_resume_listening_at_last_offset' | 'home_lvl1' | 'home_lvl1_AccountLinking' | 'home_members_lvl2' | 'player' | 'player_toc' | 'search' | 'select_group' | 'select_publication' | 'selection_lvl3'; diff --git a/webhooks/functions/src/translation/fr/fr.json b/webhooks/functions/src/translation/fr/fr.json index 212aa650..ec1814b0 100644 --- a/webhooks/functions/src/translation/fr/fr.json +++ b/webhooks/functions/src/translation/fr/fr.json @@ -51,7 +51,8 @@ "remaining": { "hoursAndMinute": "Il reste {{hours}} heures et {{minutes}} minutes.", "minute": "Il reste {{minutes}} minutes." - } + }, + "tocNotFound": "Aucune table des matières disponible." }, "test": { "player": "test player {{nb}}", diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index 8eed58a3..11ab1e10 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,9 +3,9 @@ export interface Translations { keys: { - "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "test.player" | "test.setupSdk" | "test.webhook" | "free" + "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.tocNotFound" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" + "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.tocNotFound" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } From be49f1957fb4d7463f9b62c289172c914099e46b Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 20 Dec 2021 16:12:18 +0100 Subject: [PATCH 060/180] fix: selection --- test/dev/test/test10.ts | 2 +- test/dev/test/test11.ts | 2 +- webhooks/functions/src/index.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/dev/test/test10.ts b/test/dev/test/test10.ts index b254b94b..df8d7c46 100644 --- a/test/dev/test/test10.ts +++ b/test/dev/test/test10.ts @@ -29,7 +29,7 @@ describe('My Action Test Suite', function () { test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre. Que voulez-vous faire ?`); await test.sendQuery(`selections thématiques`); - test.assertSpeech(``); + test.assertSpeech(`J'ai trouvé 2 sélections.\nnuméro 1 : liste d'essai de Philosophie.\nnuméro 2 : liste de l'auteur Emile Zola.\n\nPour choisir une sélection, dites son numéro.`); await test.sendQuery(`numéro 2`); diff --git a/test/dev/test/test11.ts b/test/dev/test/test11.ts index a51c1f76..fcee609e 100644 --- a/test/dev/test/test11.ts +++ b/test/dev/test/test11.ts @@ -30,7 +30,7 @@ describe('My Action Test Suite', function () { await test.sendQuery(`selections par genre`); - test.assertSpeech(``); + test.assertSpeech(`J'ai trouvé 2 sélections.\nnuméro 1 : liste d'essai de Philosophie.\nnuméro 2 : roman.\n\nPour choisir une sélection, dites son numéro.`); await test.sendQuery(`numéro 2`); diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 29e9622b..f7d769cd 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -283,7 +283,7 @@ app.handle('selection_lvl3__intent__selection_all_publication_lvl3', async (conv app.handle('select_group', async (conv) => { - conv.add('homeMembers.selection.listAfterSelection'); + // conv.add('homeMembers.selection.listAfterSelection'); const url = conv.session.params.groupListUrl; ok(isValidHttpUrl(url)); From 34f74cc661f5f81bfd405bc470fbfb9a267df78d Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 20 Dec 2021 16:19:29 +0100 Subject: [PATCH 061/180] =?UTF-8?q?fix:=20j'ai=20trouv=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webhooks/functions/src/index.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index f7d769cd..c54b3840 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -245,6 +245,7 @@ app.handle('selection_lvl3', (conv) => { // conv.user.params.selection.topUrl = undefined; conv.session.params.pubListUrl = ""; conv.session.params.groupListUrl = ""; + conv.session.params.nextUrlCounter = 0; conv.session.params.scene = 'selection_lvl3'; @@ -272,6 +273,8 @@ app.handle('selection_lvl3__intent__selection_my_list_lvl3', async (conv) => { conv.session.params.pubListUrl = SELECTION_URL; conv.scene.next.name = 'select_publication'; + conv.session.params.nextUrlCounter = 0; + console.log('selection_my_list_lvl3 EXIT'); }); @@ -279,6 +282,8 @@ app.handle('selection_lvl3__intent__selection_all_publication_lvl3', async (conv conv.session.params.pubListUrl = ALL_PUBLICATION_LIST_URL; conv.scene.next.name = 'select_publication'; + + conv.session.params.nextUrlCounter = 0; }); app.handle('select_group', async (conv) => { @@ -315,7 +320,7 @@ app.handle('select_group__slot__number', async (conv) => { ok(isValidHttpUrl(url), 'error.selectionPubNotDefined'); conv.session.params.pubListUrl = url; - conv.session.params.nextUrlCounter = 0; + conv.session.params.nextUrlCounter = 0; conv.scene.next.name = 'select_publication'; } else { // conv.scene.next.name = 'select_group'; From 60ea413a89661eee4189e7f88fbe692ce6171285 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 20 Dec 2021 17:15:54 +0100 Subject: [PATCH 062/180] up --- webhooks/functions/src/constants.ts | 2 + webhooks/functions/src/index.ts | 58 +++++++++++++++++++++++------ webhooks/functions/src/type.ts | 1 + 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/webhooks/functions/src/constants.ts b/webhooks/functions/src/constants.ts index bfadfe72..fc35cefa 100644 --- a/webhooks/functions/src/constants.ts +++ b/webhooks/functions/src/constants.ts @@ -6,4 +6,6 @@ export const THEMATIC_LIST_URL = 'https://storage.googleapis.com/audiobook_edrla export const GENRE_LIST_URL = 'https://storage.googleapis.com/audiobook_edrlab/navigation/genre_list.json'; export const DEFAULT_LANGUAGE: TLang = 'fr'; +export const PADDING = 5; + type TLang = 'fr' | 'en'; \ No newline at end of file diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 304217ad..e29184cb 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -15,7 +15,7 @@ import { selectPublication } from "./service/selectPublication"; import { testConversation } from "./conversation/test"; import { listGroups } from "./service/listGroups"; import { selectGroup } from "./service/selectGroups"; -import { ALL_PUBLICATION_LIST_URL, GENRE_LIST_URL, SEARCH_URL, SELECTION_URL, THEMATIC_LIST_URL } from "./constants"; +import { ALL_PUBLICATION_LIST_URL, GENRE_LIST_URL, PADDING, SEARCH_URL, SELECTION_URL, THEMATIC_LIST_URL } from "./constants"; import { i18n, t, TI18nKey } from "./translation"; const BEARER_TOKEN_NOT_DEFINED = "bearer token not defined"; @@ -29,7 +29,6 @@ export const ok: typeof __ok = (v, m) => { return __ok(v, m ? t(m): undefined); } - app.handle = (path, fn) => { const ret = appHandle(path, async (conv) => { @@ -355,7 +354,6 @@ app.handle('ask_to_resume_listening_at_last_offset__intent__yes', async (conv) = conv.scene.next.name = 'player'; }); - app.handle("ask_to_resume_listening_at_last_offset__intent__no", async (conv) => { const url = conv.user.params.player.current.url; @@ -508,6 +506,8 @@ app.handle("player", async (conv) => { startOffset: `${startTime}s`, }), ); + + conv.session.params.tocStart = 0; // reset toc }); // ---------- @@ -619,29 +619,65 @@ app.handle('player_toc', async (conv) => { const opds = new OpdsFetcher(); const webpub = await opds.webpubRequest(url); - if (!webpub?.toc) { + const tocSliceStart = conv.session.params.tocStart; + + if (webpub?.toc) { + + const toc = webpub.toc; + + const textArray = toc + .map(({ title }, i) => t('homeMembers.list.numero', { title, i: i + 1 })) + .filter((v) => v) + .slice(tocSliceStart, tocSliceStart + PADDING); + const text = textArray.join(".\n "); + + conv.add('free', { text }); + + } else { conv.add('player.tocNotFound'); - return ; } + conv.scene.next.name = "player"; +}); + +app.handle('player_toc__slot__number', async (conv) => { + + const url = conv.user.params.player.current.url; + ok(isValidHttpUrl(url), 'error.urlNotValid'); + const number = conv.intent.params?.number.resolved; + ok(typeof number === "number"); + + const opds = new OpdsFetcher(); + const webpub = await opds.webpubRequest(url); + const toc = webpub.toc; - const title = toc.map(({title}) => title).filter((v) => v).slice(0, 5); - const text = title.join(".\n "); + const tocSliceStart = conv.session.params.tocStart; - conv.add('free', { text }); + if (toc) { + const tocs = toc.slice(tocSliceStart, tocSliceStart + PADDING); + const item = toc[number]; - conv.scene.next.name = "player"; -}); + if (item) { + const itemUrl = new URL(item.url); + const time = parseInt(itemUrl.hash.split("#t=")[1], 10); -app.handle('player_toc__slot__number', (conv) => { + const readingOrders = webpub.readingOrders; + const index = readingOrders.findIndex(({url}) => url.startsWith(itemUrl.origin + itemUrl.pathname)); + if (index > -1 && time > -1) { + conv.user.params.player.current.time = time; + conv.user.params.player.current.index = index; + } + } + } conv.scene.next.name = 'player'; }); app.handle('player_toc__intent__next', (conv) => { + conv.session.params.tocStart += PADDING; conv.scene.next.name = 'player_toc'; }); diff --git a/webhooks/functions/src/type.ts b/webhooks/functions/src/type.ts index 7a925394..a93dba61 100644 --- a/webhooks/functions/src/type.ts +++ b/webhooks/functions/src/type.ts @@ -39,6 +39,7 @@ export interface IConversationWithParams extends ConversationV3 { query: string; scene: TSdkScene; nextUrlCounter: number; + tocStart: number; } } } \ No newline at end of file From dcc3f17c24fd2bc37d6f2be730990f27222af9cf Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 20 Dec 2021 17:33:06 +0100 Subject: [PATCH 063/180] up --- webhooks/functions/src/index.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index e29184cb..1797f3da 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -94,6 +94,7 @@ app.middleware(async (conv: IConversationWithParams) => query: "", nextUrlCounter: 0, scene: 'home_lvl1', + tocStart: 0, }; } @@ -612,6 +613,11 @@ app.handle('player__intent__remaining_time_player', async (conv) => { app.handle('player_toc', async (conv) => { persistMediaPlayer(conv); + // Acknowledge pause/stop + conv.add(new Media({ + mediaType: MediaType.MediaStatusACK + })); + const url = conv.user.params.player.current.url; ok(isValidHttpUrl(url), 'error.urlNotValid'); @@ -629,7 +635,7 @@ app.handle('player_toc', async (conv) => { .map(({ title }, i) => t('homeMembers.list.numero', { title, i: i + 1 })) .filter((v) => v) .slice(tocSliceStart, tocSliceStart + PADDING); - const text = textArray.join(".\n "); + const text = textArray.join(""); conv.add('free', { text }); From 354b2b72fb05a4962aa12ac4a116b0fc14a8d481 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 20 Dec 2021 18:52:06 +0100 Subject: [PATCH 064/180] fix some minor evolution --- sdk/test/actions/actions.yaml | 1 + .../actions.intent.MEDIA_STATUS_STOPPED.yaml | 1 + sdk/test/custom/scenes/home_members_lvl2.yaml | 2 ++ sdk/test/custom/scenes/player_toc.yaml | 19 +++++++++++++++++++ .../webhooks/ActionsOnGoogleFulfillment.yaml | 7 ++++++- webhooks/functions/src/index.ts | 13 +++++++++++++ webhooks/functions/src/translation/fr/fr.json | 3 ++- webhooks/functions/src/typings/i18n.d.ts | 4 ++-- 8 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 sdk/test/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml create mode 100644 sdk/test/custom/scenes/player_toc.yaml diff --git a/sdk/test/actions/actions.yaml b/sdk/test/actions/actions.yaml index f82f9c46..96f74818 100644 --- a/sdk/test/actions/actions.yaml +++ b/sdk/test/actions/actions.yaml @@ -1,2 +1,3 @@ custom: actions.intent.MAIN: {} + actions.intent.MEDIA_STATUS_STOPPED: {} diff --git a/sdk/test/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml b/sdk/test/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml new file mode 100644 index 00000000..bdb4a12f --- /dev/null +++ b/sdk/test/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml @@ -0,0 +1 @@ +transitionToScene: home_members_lvl2 diff --git a/sdk/test/custom/scenes/home_members_lvl2.yaml b/sdk/test/custom/scenes/home_members_lvl2.yaml index 109b5a28..9584671b 100644 --- a/sdk/test/custom/scenes/home_members_lvl2.yaml +++ b/sdk/test/custom/scenes/home_members_lvl2.yaml @@ -19,5 +19,7 @@ intentEvents: - handler: webhookHandler: test_webhook intent: test_webhook +- intent: menu + transitionToScene: home_members_lvl2 onEnter: webhookHandler: home_members_lvl2 diff --git a/sdk/test/custom/scenes/player_toc.yaml b/sdk/test/custom/scenes/player_toc.yaml new file mode 100644 index 00000000..7cfb9b62 --- /dev/null +++ b/sdk/test/custom/scenes/player_toc.yaml @@ -0,0 +1,19 @@ +intentEvents: +- handler: + webhookHandler: player_toc__intent__repeat + intent: repeat +- handler: + webhookHandler: player_toc__intent__next + intent: next +- handler: + webhookHandler: player_toc__intent__resume_listening_player + intent: resume_listening_player +onEnter: + webhookHandler: player_toc +onSlotUpdated: + webhookHandler: player_toc__slot__number +slots: +- name: number + required: true + type: + name: actions.type.Number diff --git a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml index bc02c429..f2c5258a 100644 --- a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml @@ -27,7 +27,6 @@ handlers: - name: test_setup_sdk - name: test_webhook - name: ask_to_resume_listening_at_last_offset__intent__no -- name: player__intent__listen_toc - name: player__intent__menu - name: select_publication__slot__number - name: select_publication__intent__resume_listening_player @@ -40,6 +39,12 @@ handlers: - name: selection_lvl3__intent__selection_all_publication_lvl3 - name: select_publication__intent__repeat - name: select_group__intent__menu +- name: player_toc +- name: player_toc__intent__repeat +- name: player_toc__intent__next +- name: player_toc__intent__resume_listening_player +- name: player_toc__slot__number +- name: player__intent__listen_toc httpsEndpoint: baseUrl: https://us-central1-valentin-5.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index c54b3840..1deeef43 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -554,6 +554,19 @@ app.handle('player__intent__resume_listening_player', (conv) => { // conv.scene.next.name = 'player'; // }); +app.handle('player__intent__listen_toc', (conv) => { + persistMediaPlayer(conv); + + conv.add('player.notAvailable'); + + // // Acknowledge pause/stop + // conv.add(new Media({ + // mediaType: 'MEDIA_STATUS_ACK' + // })); + + conv.scene.next.name = 'player'; +}); + app.handle('player__intent__menu', (conv) => { persistMediaPlayer(conv); diff --git a/webhooks/functions/src/translation/fr/fr.json b/webhooks/functions/src/translation/fr/fr.json index 212aa650..5656cd81 100644 --- a/webhooks/functions/src/translation/fr/fr.json +++ b/webhooks/functions/src/translation/fr/fr.json @@ -51,7 +51,8 @@ "remaining": { "hoursAndMinute": "Il reste {{hours}} heures et {{minutes}} minutes.", "minute": "Il reste {{minutes}} minutes." - } + }, + "notAvailable": "Fonctionnalité non disponible." }, "test": { "player": "test player {{nb}}", diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index 8eed58a3..dc0e3d4d 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,9 +3,9 @@ export interface Translations { keys: { - "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "test.player" | "test.setupSdk" | "test.webhook" | "free" + "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" + "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } From 458599a50ec0a5ad8b503ea7be65e205ba0ac12e Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 20 Dec 2021 19:02:10 +0100 Subject: [PATCH 065/180] my list redirected from home_member --- sdk/test/custom/scenes/home_members_lvl2.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sdk/test/custom/scenes/home_members_lvl2.yaml b/sdk/test/custom/scenes/home_members_lvl2.yaml index 9584671b..c3317bdb 100644 --- a/sdk/test/custom/scenes/home_members_lvl2.yaml +++ b/sdk/test/custom/scenes/home_members_lvl2.yaml @@ -21,5 +21,8 @@ intentEvents: intent: test_webhook - intent: menu transitionToScene: home_members_lvl2 +- handler: + webhookHandler: selection_lvl3__intent__selection_my_list_lvl3 + intent: selection_my_list_lvl3 onEnter: webhookHandler: home_members_lvl2 From 88c3bde8dd06697ca5ebc5b607728be74cf9c5e2 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 22 Dec 2021 12:48:00 +0100 Subject: [PATCH 066/180] feature: lance la lecture --- webhooks/functions/src/index.ts | 16 ++++++++++++++++ webhooks/functions/src/translation/fr/fr.json | 1 + webhooks/functions/src/typings/i18n.d.ts | 4 ++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 1deeef43..183e8c62 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -350,8 +350,23 @@ app.handle("ask_to_resume_listening_at_last_offset", async (conv) => { } }); +const sayAudiobookTitle = async (conv: IConversationWithParams, url: string) => { + + const opds = new OpdsFetcher(); + const webpub = await opds.webpubRequest(url); + const title = webpub.title; + + if (title) { + conv.add('player.start', {title}); + } +}; + app.handle('ask_to_resume_listening_at_last_offset__intent__yes', async (conv) => { + const url = conv.user.params.player.current.url; + ok(isValidHttpUrl(url)); + await sayAudiobookTitle(conv, url); + conv.scene.next.name = 'player'; }); @@ -361,6 +376,7 @@ app.handle("ask_to_resume_listening_at_last_offset__intent__no", async (conv) => const url = conv.user.params.player.current.url; ok(isValidHttpUrl(url), 'error.urlNotValid'); console.log("erase ", url, " resume listening NO"); + await sayAudiobookTitle(conv, url); conv.user.params.player.current.index = 0; conv.user.params.player.current.time = 0; diff --git a/webhooks/functions/src/translation/fr/fr.json b/webhooks/functions/src/translation/fr/fr.json index 5656cd81..a848524c 100644 --- a/webhooks/functions/src/translation/fr/fr.json +++ b/webhooks/functions/src/translation/fr/fr.json @@ -44,6 +44,7 @@ "search": "Que voulez-vous écouter ? Par exemple Zola." }, "player": { + "start": "Je lance la lecture de {{- title}}", "askResumeLastOffset": "Voulez-vous reprendre la lecture là où elle s'était arrêtée ?", "mediaStatus": { "notCorrect": "état de lecture incorrect." diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index dc0e3d4d..85dddc65 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,9 +3,9 @@ export interface Translations { keys: { - "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" + "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" + "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } From a903d23d2c38c0cc587b85871d6ec5ee4f03b80e Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 23 Dec 2021 14:23:01 +0100 Subject: [PATCH 067/180] fix: media status stop --- webhooks/functions/src/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 183e8c62..b6f1597b 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -17,6 +17,7 @@ import { listGroups } from "./service/listGroups"; import { selectGroup } from "./service/selectGroups"; import { ALL_PUBLICATION_LIST_URL, GENRE_LIST_URL, SEARCH_URL, SELECTION_URL, THEMATIC_LIST_URL } from "./constants"; import { i18n, t, TI18nKey } from "./translation"; +import { DefaultScenes } from "@assistant/conversation/dist/conversation/handler"; const BEARER_TOKEN_NOT_DEFINED = "bearer token not defined"; @@ -673,7 +674,8 @@ app.handle('media_status', (conv) => { mediaType: MediaType.MediaStatusACK, })); - conv.scene.next.name = "home_members_lvl2"; + // disable because need to exit the app instead + // conv.scene.next.name = DefaultScenes.End; break; default: conv.add('player.mediaStatus.notCorrect'); From 55d60342a87d06a8b026380d88a469b51f6a3b57 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 23 Dec 2021 14:23:52 +0100 Subject: [PATCH 068/180] fix: sdk dev --- sdk/test/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml | 2 +- sdk/test/custom/scenes/select_publication.yaml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/sdk/test/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml b/sdk/test/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml index bdb4a12f..af0c87f2 100644 --- a/sdk/test/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml +++ b/sdk/test/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml @@ -1 +1 @@ -transitionToScene: home_members_lvl2 +transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/test/custom/scenes/select_publication.yaml b/sdk/test/custom/scenes/select_publication.yaml index 15a01006..d2cab1b4 100644 --- a/sdk/test/custom/scenes/select_publication.yaml +++ b/sdk/test/custom/scenes/select_publication.yaml @@ -11,6 +11,8 @@ intentEvents: - handler: webhookHandler: select_publication__intent__repeat intent: repeat +- intent: menu + transitionToScene: home_members_lvl2 - handler: staticPrompt: candidates: From b2ef76fb9b24b5795f317d86019f291f5bd69c6d Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 23 Dec 2021 14:37:27 +0100 Subject: [PATCH 069/180] fix: media-status stopped --- webhooks/functions/src/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index b6f1597b..dfe83adc 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -675,7 +675,8 @@ app.handle('media_status', (conv) => { })); // disable because need to exit the app instead - // conv.scene.next.name = DefaultScenes.End; + // @ts-ignore + conv.scene.next.name = 'actions.scene.END_CONVERSATION'; break; default: conv.add('player.mediaStatus.notCorrect'); From 854dd99d0bf75ab756ffe496c16dab6284d21430 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 23 Dec 2021 18:34:40 +0100 Subject: [PATCH 070/180] fix toc --- webhooks/functions/src/index.ts | 51 ++++++++++++------- webhooks/functions/src/translation/fr/fr.json | 6 ++- webhooks/functions/src/typings/i18n.d.ts | 4 +- 3 files changed, 40 insertions(+), 21 deletions(-) diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 07a43f39..376ad5d3 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -206,6 +206,8 @@ app.handle('home_members_lvl2', (conv) => { conv.add('homeMembers.welcome1'); conv.add('homeMembers.welcome2'); + + conv.session.params.tocStart = 0; }); app.handle('home_members_lvl2__intent__listen_audiobook_lvl2', (conv) => { @@ -575,14 +577,15 @@ app.handle('player__intent__resume_listening_player', (conv) => { app.handle('player__intent__listen_toc', (conv) => { persistMediaPlayer(conv); - conv.add('player.notAvailable'); + // conv.add('player.notAvailable'); // // Acknowledge pause/stop // conv.add(new Media({ // mediaType: 'MEDIA_STATUS_ACK' // })); - conv.scene.next.name = 'player'; + // conv.scene.next.name = 'player'; + conv.scene.next.name = 'player_toc'; }); app.handle('player__intent__menu', (conv) => { @@ -641,14 +644,14 @@ app.handle('player__intent__remaining_time_player', async (conv) => { }); app.handle('player_toc', async (conv) => { - persistMediaPlayer(conv); - // Acknowledge pause/stop - conv.add(new Media({ - mediaType: MediaType.MediaStatusACK - })); + const url = conv.user.params.player?.current?.url; - const url = conv.user.params.player.current.url; + if (!url) { + conv.add('homeMembers.resumeAudiobook.noCurrentListening'); + conv.scene.next.name = 'home_members_lvl2'; + return ; + } ok(isValidHttpUrl(url), 'error.urlNotValid'); @@ -656,25 +659,24 @@ app.handle('player_toc', async (conv) => { const webpub = await opds.webpubRequest(url); const tocSliceStart = conv.session.params.tocStart; + const toc = webpub.toc; - if (webpub?.toc) { - - const toc = webpub.toc; + if (toc) { const textArray = toc .map(({ title }, i) => t('homeMembers.list.numero', { title, i: i + 1 })) .filter((v) => v) .slice(tocSliceStart, tocSliceStart + PADDING); - const text = textArray.join(""); + const text = textArray.join("") + '\n' + t('player.toc.numero'); conv.add('free', { text }); } else { - conv.add('player.tocNotFound'); + conv.add('player.toc.notFound'); } - conv.scene.next.name = "player"; + // conv.scene.next.name = "player"; }); app.handle('player_toc__slot__number', async (conv) => { @@ -691,8 +693,8 @@ app.handle('player_toc__slot__number', async (conv) => { const tocSliceStart = conv.session.params.tocStart; if (toc) { - const tocs = toc.slice(tocSliceStart, tocSliceStart + PADDING); - const item = toc[number]; + // const tocs = toc.slice(tocSliceStart, tocSliceStart + PADDING); + const item = toc[number - 1]; if (item) { const itemUrl = new URL(item.url); @@ -711,9 +713,22 @@ app.handle('player_toc__slot__number', async (conv) => { conv.scene.next.name = 'player'; }); -app.handle('player_toc__intent__next', (conv) => { +app.handle('player_toc__intent__next', async (conv) => { + + const url = conv.user.params.player.current.url; + ok(isValidHttpUrl(url), 'error.urlNotValid'); - conv.session.params.tocStart += PADDING; + const opds = new OpdsFetcher(); + const webpub = await opds.webpubRequest(url); + + const toc = webpub.toc; + const len = toc?.length || Infinity; + + if (conv.session.params.tocStart < len - PADDING) { + conv.session.params.tocStart += PADDING; + } else { + conv.add('player.toc.noNext'); + } conv.scene.next.name = 'player_toc'; }); diff --git a/webhooks/functions/src/translation/fr/fr.json b/webhooks/functions/src/translation/fr/fr.json index 86862207..389cd69f 100644 --- a/webhooks/functions/src/translation/fr/fr.json +++ b/webhooks/functions/src/translation/fr/fr.json @@ -53,7 +53,11 @@ "hoursAndMinute": "Il reste {{hours}} heures et {{minutes}} minutes.", "minute": "Il reste {{minutes}} minutes." }, - "tocNotFound": "Aucune table des matières disponible.", + "toc": { + "notFound": "Aucune table des matières disponible.", + "numero": "Choisir un numéro.", + "noNext": "Il n'y a pas de page suivante, je vais répéter la dernière page." + }, "notAvailable": "Fonctionnalité non disponible." }, "test": { diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index b8ba1ae6..04cbffa8 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,9 +3,9 @@ export interface Translations { keys: { - "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.tocNotFound" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" + "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.tocNotFound" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" + "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } From 67b616c6eec7e586ec64e292a014161691affb92 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 12 Jan 2022 14:44:49 +0100 Subject: [PATCH 071/180] fix: delete unused console.log --- webhooks/functions/src/utils/index.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/webhooks/functions/src/utils/index.ts b/webhooks/functions/src/utils/index.ts index f62e995c..2d16089f 100644 --- a/webhooks/functions/src/utils/index.ts +++ b/webhooks/functions/src/utils/index.ts @@ -39,18 +39,6 @@ export async function getPubsFromFeed(url: string): Promise<[{ webpuburl: (openAccessLinks as IOpdsLinkView[])[0].url, })); - console.log('%%%%%%%%%%%%%%'); - console.log('%%%%%%%%%%%%%%'); - console.log('%%%%%%%%%%%%%%'); - console.log('%%%%%%%%%%%%%%'); - - console.log(feed.metadata?.numberOfItems); - - console.log('%%%%%%%%%%%%%%'); - console.log('%%%%%%%%%%%%%%'); - console.log('%%%%%%%%%%%%%%'); - console.log('%%%%%%%%%%%%%%'); - return [list, feed.metadata?.numberOfItems || list.length]; } From 21e23c60b7a7a4619a625e9b7e925c2aad05117c Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Fri, 14 Jan 2022 15:56:57 +0100 Subject: [PATCH 072/180] pull from actions --- sdk/test/custom/scenes/home_members_lvl2.yaml | 2 ++ sdk/test/custom/scenes/player.yaml | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/sdk/test/custom/scenes/home_members_lvl2.yaml b/sdk/test/custom/scenes/home_members_lvl2.yaml index c3317bdb..b0d4ccf9 100644 --- a/sdk/test/custom/scenes/home_members_lvl2.yaml +++ b/sdk/test/custom/scenes/home_members_lvl2.yaml @@ -24,5 +24,7 @@ intentEvents: - handler: webhookHandler: selection_lvl3__intent__selection_my_list_lvl3 intent: selection_my_list_lvl3 +- intent: listen_toc + transitionToScene: player_toc onEnter: webhookHandler: home_members_lvl2 diff --git a/sdk/test/custom/scenes/player.yaml b/sdk/test/custom/scenes/player.yaml index 19a7b57c..4f882dde 100644 --- a/sdk/test/custom/scenes/player.yaml +++ b/sdk/test/custom/scenes/player.yaml @@ -5,8 +5,9 @@ intentEvents: - handler: webhookHandler: player__intent__remaining_time_player intent: remaing_time_player -- intent: listen_toc - transitionToScene: player_toc +- handler: + webhookHandler: player__intent__listen_toc + intent: listen_toc - handler: webhookHandler: player__intent__menu intent: menu From 328aa5647d995e51e1de7d22e6a5aa177d93ed32 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 17 Jan 2022 17:25:00 +0100 Subject: [PATCH 073/180] feature: set authorization bearer token at each http request (#20) --- webhooks/functions/package-lock.json | 5724 ++++++++++++++++- webhooks/functions/package.json | 2 +- webhooks/functions/src/constants.ts | 4 +- webhooks/functions/src/index.ts | 48 +- webhooks/functions/src/service/listGroups.ts | 2 +- .../functions/src/service/listPublication.ts | 6 +- .../functions/src/service/selectGroups.ts | 2 +- .../src/service/selectPublication.ts | 2 +- webhooks/functions/src/type.ts | 6 +- webhooks/functions/src/utils/index.ts | 15 +- 10 files changed, 5738 insertions(+), 73 deletions(-) diff --git a/webhooks/functions/package-lock.json b/webhooks/functions/package-lock.json index dcf0bcf9..6bf856bb 100644 --- a/webhooks/functions/package-lock.json +++ b/webhooks/functions/package-lock.json @@ -1,7 +1,5638 @@ { "name": "functions", + "lockfileVersion": 2, "requires": true, - "lockfileVersion": 1, + "packages": { + "": { + "name": "functions", + "dependencies": { + "@assistant/conversation": "^3.0.0", + "class-transformer": "^0.4.0", + "class-validator": "^0.13.1", + "firebase-admin": "^9.8.0", + "firebase-functions": "^3.16.0", + "i18next": "^21.5.3", + "opds-fetcher-parser": "github:edrlab/opds_fetcher_parser#eea41a1d50955f39d93670090e480834c26715b4", + "reflect-metadata": "^0.1.13" + }, + "devDependencies": { + "@types/mocha": "^9.0.0", + "@typescript-eslint/eslint-plugin": "^5.3.1", + "@typescript-eslint/parser": "^5.3.1", + "eslint": "^8.2.0", + "eslint-config-google": "^0.14.0", + "firebase-functions-test": "^0.2.0", + "mocha": "^9.1.3", + "rimraf": "^3.0.2", + "ts-node": "^10.4.0", + "typed-i18next": "^0.1.2", + "typescript": "^4.4.4", + "typescript-eslint": "0.0.1-alpha.0" + }, + "engines": { + "node": "14" + } + }, + "node_modules/@assistant/conversation": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@assistant/conversation/-/conversation-3.8.1.tgz", + "integrity": "sha512-YEyQ33xD1VCkJP16GRdXiuG55Vklbds3yiPcGSSf0hj2dj7mprWybipEZvVA4qsgv/NHrLvXPBFTySJrUpV/7g==", + "dependencies": { + "@types/aws-lambda": "^0.0.33", + "@types/debug": "^0.0.30", + "@types/express": "^4.11.1", + "@types/node": "12.12.24", + "debug": "^3.1.0", + "google-auth-library": "^6.1.0" + }, + "engines": { + "node": ">=10.18.0" + } + }, + "node_modules/@assistant/conversation/node_modules/@types/node": { + "version": "12.12.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.24.tgz", + "integrity": "sha512-1Ciqv9pqwVtW6FsIUKSZNB82E5Cu1I2bBTj1xuIHXLe/1zYLl3956Nbhg2MzSYHVfl9/rmanjbQIb7LibfCnug==" + }, + "node_modules/@assistant/conversation/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@assistant/conversation/node_modules/google-auth-library": { + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.6.tgz", + "integrity": "sha512-Q+ZjUEvLQj/lrVHF/IQwRo6p3s8Nc44Zk/DALsN+ac3T4HY/g/3rrufkgtl+nZ1TW7DNAw5cTChdVp4apUXVgQ==", + "dependencies": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@babel/runtime": { + "version": "7.16.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz", + "integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==", + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@dsherret/to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@dsherret/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha1-H2R13IvZdM6gei2vOGSzF7HdMyw=", + "dev": true, + "dependencies": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.4.tgz", + "integrity": "sha512-h8Vx6MdxwWI2WM8/zREHMoqdgLNXEL4QX3MWSVMdyNJGvXVOs+6lp+m2hc3FnuMHDc4poxFNI20vCk0OmI4G0Q==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.0.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@firebase/app-types": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.7.0.tgz", + "integrity": "sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg==" + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz", + "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/component": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.7.tgz", + "integrity": "sha512-CiAHUPXh2hn/lpzMShNmfAxHNQhKQwmQUJSYMPCjf2bCCt4Z2vLGpS+UWEuNFm9Zf8LNmkS+Z+U/s4Obi5carg==", + "dependencies": { + "@firebase/util": "1.4.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.12.2.tgz", + "integrity": "sha512-Y1LZR1LIQM8YKMkeUPpAq3/e53hcfcXO+JEZ6vCzBeD6xRawqmpw6B5/DzePdCNNvjcqheXzSaR7T39eRZo/wA==", + "dependencies": { + "@firebase/auth-interop-types": "0.1.6", + "@firebase/component": "0.5.7", + "@firebase/logger": "0.3.0", + "@firebase/util": "1.4.0", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.1.2.tgz", + "integrity": "sha512-sV32QIRSNIBj/6OYtpmPzA/SfQz1/NBZbhxg9dIhGaSt9e5HaMxXRuz2lImudX0Sd/v8DKdExrxa++K6rKrRtA==", + "dependencies": { + "@firebase/component": "0.5.7", + "@firebase/database": "0.12.2", + "@firebase/database-types": "0.9.1", + "@firebase/logger": "0.3.0", + "@firebase/util": "1.4.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/database-compat/node_modules/@firebase/database-types": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.9.1.tgz", + "integrity": "sha512-RUixK/YrbpxbfdE+nYP0wMcEsz1xPTnafP0q3UlSS/+fW744OITKtR1J0cMRaXbvY7EH0wUVTNVkrtgxYY8IgQ==", + "dependencies": { + "@firebase/app-types": "0.7.0", + "@firebase/util": "1.4.0" + } + }, + "node_modules/@firebase/database-types": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.7.3.tgz", + "integrity": "sha512-dSOJmhKQ0nL8O4EQMRNGpSExWCXeHtH57gGg0BfNAdWcKhC8/4Y+qfKLfWXzyHvrSecpLmO0SmAi/iK2D5fp5A==", + "dependencies": { + "@firebase/app-types": "0.6.3" + } + }, + "node_modules/@firebase/database-types/node_modules/@firebase/app-types": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.6.3.tgz", + "integrity": "sha512-/M13DPPati7FQHEQ9Minjk1HGLm/4K4gs9bR4rzLCWJg64yGtVC0zNg9gDpkw9yc2cvol/mNFxqTtd4geGrwdw==" + }, + "node_modules/@firebase/logger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.3.0.tgz", + "integrity": "sha512-7oQ+TctqekfgZImWkKuda50JZfkmAKMgh5qY4aR4pwRyqZXuJXN1H/BKkHvN1y0S4XWtF0f/wiCLKHhyi1ppPA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/util": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.4.0.tgz", + "integrity": "sha512-Qn58d+DVi1nGn0bA9RV89zkz0zcbt6aUcRdyiuub/SuEvjKYstWmHcHwh1C0qmE1wPf9a3a+AuaRtduaGaRT7A==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@google-cloud/common": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.7.4.tgz", + "integrity": "sha512-JO4a8l/N6fkHZ+vWgNYgcNoZh1/m6kqv8F7+NpBkGqs7NzUtkmE9WdvHaNUwAOm1mIqbuX2wXKNfAZfqZr+vMg==", + "optional": true, + "dependencies": { + "@google-cloud/projectify": "^2.0.0", + "@google-cloud/promisify": "^2.0.0", + "arrify": "^2.0.1", + "duplexify": "^4.1.1", + "ent": "^2.2.0", + "extend": "^3.0.2", + "google-auth-library": "^7.9.2", + "retry-request": "^4.2.2", + "teeny-request": "^7.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@google-cloud/firestore": { + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.15.1.tgz", + "integrity": "sha512-2PWsCkEF1W02QbghSeRsNdYKN1qavrHBP3m72gPDMHQSYrGULOaTi7fSJquQmAtc4iPVB2/x6h80rdLHTATQtA==", + "optional": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "functional-red-black-tree": "^1.0.1", + "google-gax": "^2.24.1", + "protobufjs": "^6.8.6" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@google-cloud/paginator": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.6.tgz", + "integrity": "sha512-XCTm/GfQIlc1ZxpNtTSs/mnZxC2cePNhxU3X8EzHXKIJ2JFncmJj2Fcd2IP+gbmZaSZnY0juFxbUCkIeuu/2eQ==", + "optional": true, + "dependencies": { + "arrify": "^2.0.0", + "extend": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@google-cloud/projectify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.1.1.tgz", + "integrity": "sha512-+rssMZHnlh0twl122gXY4/aCrk0G1acBqkHFfYddtsqpYXGxA29nj9V5V9SfC+GyOG00l650f6lG9KL+EpFEWQ==", + "optional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@google-cloud/promisify": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.4.tgz", + "integrity": "sha512-j8yRSSqswWi1QqUGKVEKOG03Q7qOoZP6/h2zN2YO+F5h2+DHU0bSrHCK9Y7lo2DI9fBd8qGAw795sf+3Jva4yA==", + "optional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@google-cloud/storage": { + "version": "5.15.3", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.15.3.tgz", + "integrity": "sha512-a2Y+mvfbzznWorQiv6c+qdPDlBpe47tikV8tpQSnvYXz1Ed/rjin41k2nKUQUcAPGHtYeTzGfKnCNKC+lv8qRg==", + "optional": true, + "dependencies": { + "@google-cloud/common": "^3.7.4", + "@google-cloud/paginator": "^3.0.0", + "@google-cloud/promisify": "^2.0.0", + "arrify": "^2.0.0", + "async-retry": "^1.3.1", + "compressible": "^2.0.12", + "date-and-time": "^2.0.0", + "duplexify": "^4.0.0", + "extend": "^3.0.2", + "gcs-resumable-upload": "^3.3.0", + "get-stream": "^6.0.0", + "hash-stream-validation": "^0.2.2", + "mime": "^2.2.0", + "mime-types": "^2.0.8", + "p-limit": "^3.0.1", + "pumpify": "^2.0.0", + "snakeize": "^0.1.0", + "stream-events": "^1.0.1", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.4.2.tgz", + "integrity": "sha512-aUN6oGk9un8rfYWz73nQgFxPCYJQYd8LpIGguZHBsNduBMyqG6EWANrsVBuTG+nl/l4dKb3x+qi1l9+oxDxqGg==", + "optional": true, + "dependencies": { + "@grpc/proto-loader": "^0.6.4", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.6.tgz", + "integrity": "sha512-cdMaPZ8AiFz6ua6PUbP+LKbhwJbFXnrQ/mlnKGUyzDUZ3wp7vPLksnmLCBX6SHgSmjX7CbNVNLFYD5GmmjO4GQ==", + "optional": true, + "dependencies": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^6.10.0", + "yargs": "^16.1.1" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.6.0.tgz", + "integrity": "sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@panva/asn1.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", + "integrity": "sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=", + "optional": true + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "optional": true + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "optional": true + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=", + "optional": true + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "optional": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=", + "optional": true + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=", + "optional": true + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=", + "optional": true + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=", + "optional": true + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", + "optional": true + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "optional": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "node_modules/@types/aws-lambda": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-0.0.33.tgz", + "integrity": "sha512-p13MzAb/1ZJK1h0jDhRjdFqlRHC44HAOS7qYuVpn7NnFDv8UdNbRjExfhK69syvI9IoIR4NN4dRGjpVDsN6tEQ==" + }, + "node_modules/@types/body-parser": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz", + "integrity": "sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cors": { + "version": "2.8.12", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" + }, + "node_modules/@types/debug": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-0.0.30.tgz", + "integrity": "sha512-orGL5LXERPYsLov6CWs3Fh6203+dXzJkR7OnddIr2514Hsecwc8xRpzCapshBbKFImCsvS/mk6+FWiN5LyZJAQ==" + }, + "node_modules/@types/express": { + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", + "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-jwt": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@types/express-jwt/-/express-jwt-0.0.42.tgz", + "integrity": "sha512-WszgUddvM1t5dPpJ3LhWNH8kfNN8GPIBrAGxgIYXVCEGx6Bx4A036aAuf/r5WH9DIEdlmp7gHOYvSM6U87B0ag==", + "dependencies": { + "@types/express": "*", + "@types/express-unless": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.24", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.24.tgz", + "integrity": "sha512-3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/express-unless": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.2.tgz", + "integrity": "sha512-Q74UyYRX/zIgl1HSp9tUX2PlG8glkVm+59r7aK4KGKzC5jqKIOX6rrVLRQrzpZUQ84VukHtRoeAuon2nIssHPQ==", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/fs-extra": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz", + "integrity": "sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "node_modules/@types/lodash": { + "version": "4.14.176", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.176.tgz", + "integrity": "sha512-xZmuPTa3rlZoIbtDUyJKZQimJV3bxCmzMIO2c9Pz9afyDro6kr7R79GwcB6mRhuoPmV2p1Vb66WOJH7F886WKQ==", + "dev": true + }, + "node_modules/@types/long": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", + "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==", + "optional": true + }, + "node_modules/@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "node_modules/@types/mocha": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.0.0.tgz", + "integrity": "sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "16.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz", + "integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==" + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + }, + "node_modules/@types/serve-static": { + "version": "1.13.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", + "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/validator": { + "version": "13.6.6", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.6.6.tgz", + "integrity": "sha512-+qogUELb4gMhrMjSh/seKmGVvN+uQLfyqJAqYRWqVHsvBsUO2xDBCL8CJ/ZSukbd8vXaoYbpIssAmfLEzzBHEw==" + }, + "node_modules/@types/xmldom": { + "version": "0.1.31", + "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.31.tgz", + "integrity": "sha512-bVy7s0nvaR5D1mT1a8ZkByHWNOGb6Vn4yi5TWhEdmyKlAG+08SA7Md6+jH+tYmMLueAwNeWvHHpeKrr6S4c4BA==" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.3.1.tgz", + "integrity": "sha512-cFImaoIr5Ojj358xI/SDhjog57OK2NqlpxwdcgyxDA3bJlZcJq5CPzUXtpD7CxI2Hm6ATU7w5fQnnkVnmwpHqw==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "5.3.1", + "@typescript-eslint/scope-manager": "5.3.1", + "debug": "^4.3.2", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.2.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.3.1.tgz", + "integrity": "sha512-RgFn5asjZ5daUhbK5Sp0peq0SSMytqcrkNfU4pnDma2D8P3ElZ6JbYjY8IMSFfZAJ0f3x3tnO3vXHweYg0g59w==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.3.1", + "@typescript-eslint/types": "5.3.1", + "@typescript-eslint/typescript-estree": "5.3.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.3.1.tgz", + "integrity": "sha512-TD+ONlx5c+Qhk21x9gsJAMRohWAUMavSOmJgv3JGy9dgPhuBd5Wok0lmMClZDyJNLLZK1JRKiATzCKZNUmoyfw==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.3.1", + "@typescript-eslint/types": "5.3.1", + "@typescript-eslint/typescript-estree": "5.3.1", + "debug": "^4.3.2" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.3.1.tgz", + "integrity": "sha512-XksFVBgAq0Y9H40BDbuPOTUIp7dn4u8oOuhcgGq7EoDP50eqcafkMVGrypyVGvDYHzjhdUCUwuwVUK4JhkMAMg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.3.1", + "@typescript-eslint/visitor-keys": "5.3.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.3.1.tgz", + "integrity": "sha512-bG7HeBLolxKHtdHG54Uac750eXuQQPpdJfCYuw4ZI3bZ7+GgKClMWM8jExBtp7NSP4m8PmLRM8+lhzkYnSmSxQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.3.1.tgz", + "integrity": "sha512-PwFbh/PKDVo/Wct6N3w+E4rLZxUDgsoII/GrWM2A62ETOzJd4M6s0Mu7w4CWsZraTbaC5UQI+dLeyOIFF1PquQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.3.1", + "@typescript-eslint/visitor-keys": "5.3.1", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.3.1.tgz", + "integrity": "sha512-3cHUzUuVTuNHx0Gjjt5pEHa87+lzyqOiHXy/Gz+SJOCW1mpw9xQHIIEwnKn+Thph1mgWyZ90nboOcSuZr/jTTQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.3.1", + "eslint-visitor-keys": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "devOptional": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-differ": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "engines": { + "node": ">=8" + } + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "optional": true, + "dependencies": { + "retry": "0.13.1" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/bignumber.js": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", + "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "engines": { + "node": "*" + } + }, + "node_modules/binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "node_modules/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + }, + "node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", + "engines": { + "node": ">=0.2.0" + } + }, + "node_modules/bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "node_modules/chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", + "dependencies": { + "traverse": ">=0.3.0 <0.4" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/class-transformer": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.4.0.tgz", + "integrity": "sha512-ETWD/H2TbWbKEi7m9N4Km5+cw1hNcqJSxlSYhsLsNjQzWWiZIYA1zafxpK9PwVfaZ6AqR5rrjPVUBGESm5tQUA==" + }, + "node_modules/class-validator": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.13.1.tgz", + "integrity": "sha512-zWIeYFhUitvAHBwNhDdCRK09hWx+P0HUwFE8US8/CxFpMVzkUK8RJl7yOIE+BVu2lxyPNgeOaFv78tLE47jBIg==", + "dependencies": { + "@types/validator": "^13.1.3", + "libphonenumber-js": "^1.9.7", + "validator": "^13.5.2" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "devOptional": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/code-block-writer": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-10.1.1.tgz", + "integrity": "sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==", + "dev": true + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "devOptional": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "devOptional": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "dev": true + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "optional": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "node_modules/configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "optional": true, + "dependencies": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-disposition/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/date-and-time": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-2.0.1.tgz", + "integrity": "sha512-O7Xe5dLaqvY/aF/MFWArsAM1J4j7w1CSZlPCX9uHgmb+6SbkPd8Q4YOvfvH/cZGvFlJFfHOZKxQtmMUOoZhc/w==", + "optional": true + }, + "node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "node_modules/dicer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", + "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", + "dependencies": { + "streamsearch": "0.1.2" + }, + "engines": { + "node": ">=4.5.0" + } + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "optional": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexer2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "optional": true, + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "devOptional": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "optional": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "optional": true + }, + "node_modules/err-code": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", + "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=" + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "devOptional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.2.0.tgz", + "integrity": "sha512-erw7XmM+CLxTOickrimJ1SiF55jiNlVSp2qqm0NuBWPtHYQCegD5ZMaW0c3i5ytPqL+SSLaCxdvQXFPLJn+ABw==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.0.4", + "@humanwhocodes/config-array": "^0.6.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^6.0.0", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.2.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-google": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", + "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", + "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-6.0.0.tgz", + "integrity": "sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/espree": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.0.0.tgz", + "integrity": "sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ==", + "dev": true, + "dependencies": { + "acorn": "^8.5.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/express/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fast-text-encoding": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", + "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==" + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fetch-cookie": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-1.0.0.tgz", + "integrity": "sha512-SWcAhkDe4yVBFtwRqJNmot6k1XjjzI7tw3aRHepxXrK6FQp6obBhqcnsdm2aNUzrtE71607crNAYodtKMq3TjA==", + "dependencies": { + "tough-cookie": "^2.3.3 || ^3.0.1 || ^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-js": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/file-js/-/file-js-0.3.0.tgz", + "integrity": "sha1-+rRr94I0bJKUSZ8fDSrQfYOPJdE=", + "dependencies": { + "bluebird": "^3.4.7", + "minimatch": "^3.0.3", + "proper-lockfile": "^1.2.0" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "node_modules/filehound": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/filehound/-/filehound-1.17.5.tgz", + "integrity": "sha512-BsNTM3xoscYKgv0quE9RWPVhu5ZTb7BNu3H/IbZQbOfQeA7ZyOV/hIYfo60H3Jhorw/J5vbg59KHS1UCHt4FAw==", + "dependencies": { + "bluebird": "^3.7.2", + "file-js": "0.3.0", + "lodash": "^4.17.21", + "minimatch": "^3.0.4", + "moment": "^2.29.1", + "unit-compare": "^1.0.1" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/firebase-admin": { + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.12.0.tgz", + "integrity": "sha512-AtA7OH5RbIFGoc0gZOQgaYC6cdjdhZv4w3XgWoupkPKO1HY+0GzixOuXDa75kFeoVyhIyo4PkLg/GAC1dC1P6w==", + "dependencies": { + "@firebase/database-compat": "^0.1.1", + "@firebase/database-types": "^0.7.2", + "@types/node": ">=12.12.47", + "dicer": "^0.3.0", + "jsonwebtoken": "^8.5.1", + "jwks-rsa": "^2.0.2", + "node-forge": "^0.10.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "optionalDependencies": { + "@google-cloud/firestore": "^4.5.0", + "@google-cloud/storage": "^5.3.0" + } + }, + "node_modules/firebase-functions": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.16.0.tgz", + "integrity": "sha512-6ISOn0JckMtpA3aJ/+wCCGhThUhBUrpZD+tSkUeolx0Vr+NoYFXA0+2YzJZa/A2MDU8gotPzUtnauLSEQvfClQ==", + "dependencies": { + "@types/cors": "^2.8.5", + "@types/express": "4.17.3", + "cors": "^2.8.5", + "express": "^4.17.1", + "lodash": "^4.17.14" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + }, + "peerDependencies": { + "firebase-admin": "^8.0.0 || ^9.0.0 || ^10.0.0" + } + }, + "node_modules/firebase-functions-test": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/firebase-functions-test/-/firebase-functions-test-0.2.3.tgz", + "integrity": "sha512-zYX0QTm53wCazuej7O0xqbHl90r/v1PTXt/hwa0jo1YF8nDM+iBKnLDlkIoW66MDd0R6aGg4BvKzTTdJpvigUA==", + "dev": true, + "dependencies": { + "@types/lodash": "^4.14.104", + "lodash": "^4.17.5" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "firebase-admin": ">=6.0.0", + "firebase-functions": ">=2.0.0" + } + }, + "node_modules/firebase-functions/node_modules/@types/express": { + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.3.tgz", + "integrity": "sha512-I8cGRJj3pyOLs/HndoP+25vOqhqWkAZsWMEmq1qXy/b/M3ppufecUwaK2/TVDVxcV61/iSdhykUjQQ2DLSrTdg==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "*", + "@types/serve-static": "*" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flatted": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", + "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", + "dev": true + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/fstream/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "devOptional": true + }, + "node_modules/gaxios": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.2.tgz", + "integrity": "sha512-T+ap6GM6UZ0c4E6yb1y/hy2UB6hTrqhglp3XfmU9qbLCGRYhLVV5aRPpC4EmoG8N8zOnkYCgoBz+ScvGAARY6Q==", + "dependencies": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gcp-metadata": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.1.tgz", + "integrity": "sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==", + "dependencies": { + "gaxios": "^4.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gcs-resumable-upload": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/gcs-resumable-upload/-/gcs-resumable-upload-3.3.1.tgz", + "integrity": "sha512-WyC0i4VkslIdrdmeM5PNuGzANALLXTG5RoHb08OE30gYT+FEvCDPiA8KOjV2s1wOu9ngEW4+IuzBjtP/ni7UdQ==", + "optional": true, + "dependencies": { + "abort-controller": "^3.0.0", + "configstore": "^5.0.0", + "extend": "^3.0.2", + "gaxios": "^4.0.0", + "google-auth-library": "^7.0.0", + "pumpify": "^2.0.0", + "stream-events": "^1.0.4" + }, + "bin": { + "gcs-upload": "build/src/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "devOptional": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dependencies": { + "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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/google-auth-library": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.10.1.tgz", + "integrity": "sha512-nQxgM1ZopUMcpMnu95kOSzI+9tJl4YDOZJomSTBGlRLpxfBopdwto7WvzoI87HuN0nQqVETgOsHi/C/po1rppA==", + "optional": true, + "dependencies": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/google-gax": { + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.28.0.tgz", + "integrity": "sha512-kuqc8a4+CTCMBcF3tlOL7Sa74JWkTzcZxatAQTCVK35WToXkHnJ0qncFOJuegUv3EbV9IQY4j/+NZdFLv+lbTA==", + "optional": true, + "dependencies": { + "@grpc/grpc-js": "~1.4.0", + "@grpc/proto-loader": "^0.6.1", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "fast-text-encoding": "^1.0.3", + "google-auth-library": "^7.6.1", + "is-stream-ended": "^0.1.4", + "node-fetch": "^2.6.1", + "object-hash": "^2.1.1", + "proto3-json-serializer": "^0.1.1", + "protobufjs": "6.11.2", + "retry-request": "^4.0.0" + }, + "bin": { + "compileProtos": "build/tools/compileProtos.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/google-p12-pem": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.2.tgz", + "integrity": "sha512-tjf3IQIt7tWCDsa0ofDQ1qqSCNzahXDxdAGJDbruWqu3eCg5CKLYKN+hi0s6lfvzYZ1GDVr+oDF9OOWlDSdf0A==", + "dependencies": { + "node-forge": "^0.10.0" + }, + "bin": { + "gp12-pem": "build/src/bin/gp12-pem.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "engines": { + "node": ">=4.x" + } + }, + "node_modules/gtoken": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.3.1.tgz", + "integrity": "sha512-yqOREjzLHcbzz1UrQoxhBtpk8KjrVhuqPE7od1K2uhyxG2BHjKZetlbLw/SPZak/QqTIQW+addS+EcjqQsZbwQ==", + "dependencies": { + "gaxios": "^4.0.0", + "google-p12-pem": "^3.0.3", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hash-stream-validation": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.4.tgz", + "integrity": "sha512-Gjzu0Xn7IagXVkSu9cSFuK1fqzwtLwFhNhVL8IFJijRNMgUttFbBSIAzKuSIrsFMO1+g1RlsoN49zPIbwPDMGQ==", + "optional": true + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "node_modules/http-parser-js": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", + "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==" + }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "optional": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/i18next": { + "version": "21.5.3", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.5.3.tgz", + "integrity": "sha512-9R8127a0/N5okiD7eeo6XBPQsHgHsLr1GdQEa35Pcw305ArC9KZDLs9kbgdn3xuVUNYlVu8+gWzz73eVkna0gA==", + "dependencies": { + "@babel/runtime": "^7.12.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz", + "integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.0.tgz", + "integrity": "sha512-JLJ6OwBfO1KcA+TvJT+v8gbE6iWbj24LyDNFgFEN0lzegn6cC6a/p3NIDaepMsJjQjlUWqIC7wJv8lBFxPNjcw==", + "dependencies": { + "queue": "6.0.2" + }, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "devOptional": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "dependencies": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "dependencies": { + "is-unc-path": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-stream-ended": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", + "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==", + "optional": true + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "node_modules/is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "dependencies": { + "unc-path-regex": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "node_modules/jose": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.5.tgz", + "integrity": "sha512-BAiDNeDKTMgk4tvD0BbxJ8xHEHBZgpeRZ1zGPPsitSyMgjoMWiLGYAE7H7NpP5h0lPppQajQs871E8NHUrzVPA==", + "dependencies": { + "@panva/asn1.js": "^1.0.0" + }, + "engines": { + "node": ">=10.13.0 < 13 || >=13.7.0" + }, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=4", + "npm": ">=1.4.28" + } + }, + "node_modules/jsonwebtoken/node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jwks-rsa": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.0.5.tgz", + "integrity": "sha512-fliHfsiBRzEU0nXzSvwnh0hynzGB0WihF+CinKbSRlaqRxbqqKf2xbBPgwc8mzf18/WgwlG8e5eTpfSTBcU4DQ==", + "dependencies": { + "@types/express-jwt": "0.0.42", + "debug": "^4.3.2", + "jose": "^2.0.5", + "limiter": "^1.1.5", + "lru-memoizer": "^2.1.4" + }, + "engines": { + "node": ">=10 < 13 || >=14" + } + }, + "node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/libphonenumber-js": { + "version": "1.9.42", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.9.42.tgz", + "integrity": "sha512-UBtU0ylpZPKPT8NLIyQJWj/DToMFxmo3Fm5m6qDc0LATvf0SY0qUhaurCEvukAB9Fo+Ia2Anjzqwoupaa64fXg==" + }, + "node_modules/limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, + "node_modules/listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "optional": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/loglevel": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz", + "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/loglevel-plugin-prefix": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", + "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", + "dev": true + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "optional": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lru-memoizer": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.1.4.tgz", + "integrity": "sha512-IXAq50s4qwrOBrXJklY+KhgZF+5y98PDaNo0gi/v2KQBFLyWr+JyFvijZXkGKjQj/h9c0OwoE+JZbwUXce76hQ==", + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "~4.0.0" + } + }, + "node_modules/lru-memoizer/node_modules/lru-cache": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", + "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=", + "dependencies": { + "pseudomap": "^1.0.1", + "yallist": "^2.0.0" + } + }, + "node_modules/lru-memoizer/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "optional": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", + "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.33", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", + "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", + "dependencies": { + "mime-db": "1.50.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mocha": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz", + "integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==", + "dev": true, + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.2", + "debug": "4.3.2", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.7", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.1.25", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.1.5", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mocha/node_modules/nanoid": { + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", + "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mocha/node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/multimatch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz", + "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==", + "dev": true, + "dependencies": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nanoid": { + "version": "3.1.30", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz", + "integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/node-stream-zip": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.15.0.tgz", + "integrity": "sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw==", + "engines": { + "node": ">=0.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/antelle" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "optional": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/opds-fetcher-parser": { + "version": "0.1.0", + "resolved": "git+ssh://git@github.com/edrlab/opds_fetcher_parser.git#eea41a1d50955f39d93670090e480834c26715b4", + "integrity": "sha512-tAgaTwyAL0sqwaCsrO0EzYu5GwOw9A377dYa7ArMk64Ydft2nLktP5/D2PFACzhO3BYEWZCLDzDy5HlSOOnIkw==", + "license": "BSD-3-Clause", + "dependencies": { + "moment": "^2.29.1", + "nanoid": "^3.1.23", + "r2-lcp-js": "^1.0.30", + "r2-opds-js": "^1.0.35", + "r2-shared-js": "^1.0.51", + "ts-fetch": "github:edrlab/ts_fetch#709719be762e4921b6e935f5d7105764cfaccae4" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "devOptional": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "node_modules/picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/proper-lockfile": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-1.2.0.tgz", + "integrity": "sha1-zv9d2J0+XxD7deHo52vHWAGlnDQ=", + "dependencies": { + "err-code": "^1.0.0", + "extend": "^3.0.0", + "graceful-fs": "^4.1.2", + "retry": "^0.10.0" + } + }, + "node_modules/proper-lockfile/node_modules/retry": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", + "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", + "engines": { + "node": "*" + } + }, + "node_modules/proto3-json-serializer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-0.1.5.tgz", + "integrity": "sha512-G395jcZkgNXNeS+6FGqd09TsXeoCs9wmBWByDiwFy7Yd7HD8pyfyvf6q+rGh7PhT4AshRpG4NowzoKYUtkNjKg==", + "optional": true + }, + "node_modules/protobufjs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", + "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "optional": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pumpify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", + "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", + "optional": true, + "dependencies": { + "duplexify": "^4.1.1", + "inherits": "^2.0.3", + "pump": "^3.0.0" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/queue": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", + "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "dependencies": { + "inherits": "~2.0.3" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/r2-lcp-js": { + "version": "1.0.33", + "resolved": "https://registry.npmjs.org/r2-lcp-js/-/r2-lcp-js-1.0.33.tgz", + "integrity": "sha512-WNPVjHd1v8appnAqGZ/B8DlRm4k0JdixOc1TSwF+FSrjcBidG+CWijozFEBdPF+DT6FQAZcBc91B+Oc4qw3OJg==", + "dependencies": { + "bindings": "^1.5.0", + "debug": "^4.3.2", + "moment": "^2.29.1", + "r2-utils-js": "^1.0.27", + "request": "^2.88.2", + "request-promise-native": "^1.0.9", + "ta-json-x": "^2.5.3", + "tslib": "^2.3.1", + "urijs": "^1.19.7" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1.0" + } + }, + "node_modules/r2-opds-js": { + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/r2-opds-js/-/r2-opds-js-1.0.38.tgz", + "integrity": "sha512-yZB1BFmfrxgvIIe1t+p7nWrMcSS+8ge9NJIDaPe1Zq6rHpC8IlBy5HvdCgGN6pX7Ix1u3VbI1zy/KxVFUPzAsg==", + "dependencies": { + "debug": "^4.3.2", + "r2-lcp-js": "^1.0.33", + "r2-shared-js": "^1.0.53", + "r2-utils-js": "^1.0.27", + "ta-json-x": "^2.5.3", + "tslib": "^2.3.1", + "xmldom": "^0.6.0" + }, + "engines": { + "node": ">=16", + "npm": ">=8" + } + }, + "node_modules/r2-shared-js": { + "version": "1.0.53", + "resolved": "https://registry.npmjs.org/r2-shared-js/-/r2-shared-js-1.0.53.tgz", + "integrity": "sha512-1LyAd5Ebhyfe2gRFg8wE0wS9yK+bYDBfRZLpCxCX5O3JNdSwuVwLAff6qLhk7ExagifFRB4ZUNMpW1n3zEUi+Q==", + "dependencies": { + "debug": "^4.3.2", + "fast-deep-equal": "^3.1.3", + "image-size": "^1.0.0", + "mime-types": "^2.1.33", + "moment": "^2.29.1", + "r2-lcp-js": "^1.0.33", + "r2-utils-js": "^1.0.27", + "slugify": "^1.6.1", + "ta-json-x": "^2.5.3", + "tslib": "^2.3.1", + "xmldom": "^0.6.0", + "xpath": "^0.0.32", + "yazl": "^2.5.1" + }, + "bin": { + "r2-shared-js-cli": "dist/es6-es2015/src/_utils/cli.js" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1.0" + } + }, + "node_modules/r2-utils-js": { + "version": "1.0.27", + "resolved": "https://registry.npmjs.org/r2-utils-js/-/r2-utils-js-1.0.27.tgz", + "integrity": "sha512-uZ0P/JBKY16JAsL5FwH/r2k+9Jq30i7IdWxsa26mki/2DHALE4lv+Qs80kU68pHWKXS+eeriyCkCTCmI32TJTw==", + "dependencies": { + "@types/xmldom": "^0.1.31", + "debug": "^4.3.2", + "filehound": "^1.17.5", + "node-stream-zip": "^1.15.0", + "reflect-metadata": "^0.1.13", + "request": "^2.88.2", + "request-promise-native": "^1.0.9", + "ta-json-x": "^2.5.3", + "tslib": "^2.3.1", + "unzipper": "^0.10.11", + "xpath": "^0.0.32", + "yauzl": "^2.10.0", + "yazl": "^2.5.1" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1.0" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + }, + "node_modules/regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "dependencies": { + "lodash": "^4.17.19" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request-promise-native": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", + "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", + "dependencies": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "engines": { + "node": ">=0.12.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "optional": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/retry-request": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.2.2.tgz", + "integrity": "sha512-xA93uxUD/rogV7BV59agW/JHPGXeREMWiZc9jhcwY4YdZ7QOtC7qbomYg0n4wyk2lJhggjvKvhNX8wln/Aldhg==", + "optional": true, + "dependencies": { + "debug": "^4.1.1", + "extend": "^3.0.2" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "optional": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "node_modules/setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", + "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", + "optional": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slugify": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.2.tgz", + "integrity": "sha512-XMtI8qD84LwCpthLMBHlIhcrj10cgA+U/Ot8G6FD6uFuWZtMfKK75JO7l81nzpFJsPlsW6LT+VKqWQJW3+6New==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/snakeize": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/snakeize/-/snakeize-0.1.0.tgz", + "integrity": "sha1-EMCI2LWOsHazIpu1oE4jLOEmQi0=", + "optional": true + }, + "node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stream-events": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", + "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "optional": true, + "dependencies": { + "stubs": "^3.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "optional": true + }, + "node_modules/streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "optional": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "devOptional": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "devOptional": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=", + "optional": true + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ta-json-x": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/ta-json-x/-/ta-json-x-2.5.3.tgz", + "integrity": "sha512-zhn9oZJVUOj73/WmLFoLszp8+zl8RZAU995dTQWhZK/2eSvFiz2eZ3nN6Kk7B6lRg2GUWnW1v3S3IUhFNbwYQA==", + "dependencies": { + "reflect-metadata": "^0.1.13" + } + }, + "node_modules/teeny-request": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.1.3.tgz", + "integrity": "sha512-Ew3aoFzgQEatLA5OBIjdr1DWJUaC1xardG+qbPPo5k/y/3fMwXLxpjh5UB5dVfElktLaQbbMs80chkz53ByvSg==", + "optional": true, + "dependencies": { + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.1", + "stream-events": "^1.0.5", + "uuid": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "node_modules/traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", + "engines": { + "node": "*" + } + }, + "node_modules/ts-fetch": { + "version": "0.1.0", + "resolved": "git+ssh://git@github.com/edrlab/ts_fetch.git#709719be762e4921b6e935f5d7105764cfaccae4", + "integrity": "sha512-oAbmjoqcPa4E0F0L7RYsGDy0MuYZBWfvt4cG791uZhHNrd0NCgkBGhgbTt8OIQCC4mGiXaqQH6ovGy7g3hxMVg==", + "license": "BSD-3-Clause", + "dependencies": { + "fetch-cookie": "^1.0.0", + "node-fetch": "^2.6.7", + "tough-cookie": "^4.0.0" + } + }, + "node_modules/ts-fetch/node_modules/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ts-morph": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-4.3.3.tgz", + "integrity": "sha512-yauxRJM4Vo+KvpJFgL4Mp9PtFjwZVrt54eP3RkLIXnaaAY5TGVHTLqN2OnLGwf6YjyqkDLAKprZVOUTvVEz6ZQ==", + "dev": true, + "dependencies": { + "@dsherret/to-absolute-glob": "^2.0.2", + "chalk": "^2.4.2", + "code-block-writer": "^10.0.0", + "fs-extra": "^8.1.0", + "glob-parent": "^5.1.0", + "globby": "^10.0.1", + "is-negated-glob": "^1.0.0", + "multimatch": "^4.0.0", + "typescript": "3.0.1 - 3.6.4" + } + }, + "node_modules/ts-morph/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ts-morph/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ts-morph/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/ts-morph/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/ts-morph/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ts-morph/node_modules/globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-morph/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ts-morph/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ts-morph/node_modules/typescript": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz", + "integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/ts-node": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", + "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-i18next": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/typed-i18next/-/typed-i18next-0.1.2.tgz", + "integrity": "sha512-3Zn04Enaz55WSLKKxj31+pYSvWicYpFAMdIClcErtxLdwU6p1aZ9QU9vhMwYE0qrXSxBTIvViZSy5J54arhJqQ==", + "dev": true, + "dependencies": { + "@types/fs-extra": "^8.0.0", + "chalk": "^2.4.2", + "commander": "^3.0.2", + "fs-extra": "^8.1.0", + "loglevel": "^1.6.4", + "loglevel-plugin-prefix": "^0.8.4", + "ts-morph": "^4.2.0", + "upath": "^1.2.0" + }, + "bin": { + "typed-i18next": "dist/cli/main.js" + } + }, + "node_modules/typed-i18next/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/typed-i18next/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/typed-i18next/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/typed-i18next/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/typed-i18next/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/typed-i18next/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/typed-i18next/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "optional": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", + "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/typescript-eslint": { + "version": "0.0.1-alpha.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-0.0.1-alpha.0.tgz", + "integrity": "sha512-1hNKM37dAWML/2ltRXupOq2uqcdRQyDFphl+341NTPXFLLLiDhErXx8VtaSLh3xP7SyHZdcCgpt9boYYVb3fQg==", + "dev": true + }, + "node_modules/unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "optional": true, + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/unit-compare": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unit-compare/-/unit-compare-1.0.1.tgz", + "integrity": "sha1-DHRZ8OW/U2N+qHPKPO4Y3i7so4Y=", + "dependencies": { + "moment": "^2.14.1" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unzipper": { + "version": "0.10.11", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz", + "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", + "dependencies": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "graceful-fs": "^4.2.2", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" + } + }, + "node_modules/unzipper/node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=" + }, + "node_modules/unzipper/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/unzipper/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/unzipper/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true, + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urijs": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.7.tgz", + "integrity": "sha512-Id+IKjdU0Hx+7Zx717jwLPsPeUqz7rAtuVBRLLs+qn+J2nf9NGITWVCxcijgYxBqe83C7sqsQPs6H1pyz3x9gA==" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/validator": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", + "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workerpool": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", + "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "devOptional": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "optional": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/xmldom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz", + "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/xpath": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz", + "integrity": "sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==", + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "devOptional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "devOptional": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "devOptional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yazl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", + "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", + "dependencies": { + "buffer-crc32": "~0.2.3" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "devOptional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, "dependencies": { "@assistant/conversation": { "version": "3.8.1", @@ -113,7 +5744,8 @@ "@firebase/auth-interop-types": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz", - "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==" + "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==", + "requires": {} }, "@firebase/component": { "version": "0.5.7", @@ -731,7 +6363,8 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true + "dev": true, + "requires": {} }, "acorn-walk": { "version": "8.2.0", @@ -767,12 +6400,14 @@ "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "devOptional": true }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "devOptional": true, "requires": { "color-convert": "^2.0.1" } @@ -1065,6 +6700,7 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "devOptional": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -1081,6 +6717,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "devOptional": true, "requires": { "color-name": "~1.1.4" } @@ -1088,7 +6725,8 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "devOptional": true }, "combined-stream": { "version": "1.0.8", @@ -1363,7 +7001,8 @@ "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "devOptional": true }, "encodeurl": { "version": "1.0.2", @@ -1402,7 +7041,8 @@ "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "devOptional": true }, "escape-html": { "version": "1.0.3", @@ -1507,7 +7147,8 @@ "version": "0.14.0", "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", - "dev": true + "dev": true, + "requires": {} }, "eslint-scope": { "version": "5.1.1", @@ -1983,7 +7624,8 @@ "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "devOptional": true }, "gaxios": { "version": "4.3.2", @@ -2024,7 +7666,8 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "devOptional": true }, "get-stream": { "version": "6.0.1", @@ -2281,7 +7924,8 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "devOptional": true }, "inflight": { "version": "1.0.6", @@ -2330,7 +7974,8 @@ "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "devOptional": true }, "is-glob": { "version": "4.0.3", @@ -2925,9 +8570,9 @@ "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, "node-fetch": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", - "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "requires": { "whatwg-url": "^5.0.0" } @@ -2981,15 +8626,16 @@ } }, "opds-fetcher-parser": { - "version": "github:panaC/opds_fetcher_parser#46f59a92513c17a060d02dfceb82633bbbbc4be3", - "from": "github:panaC/opds_fetcher_parser#46f59a92513c17a060d02dfceb82633bbbbc4be3", + "version": "git+ssh://git@github.com/edrlab/opds_fetcher_parser.git#eea41a1d50955f39d93670090e480834c26715b4", + "integrity": "sha512-tAgaTwyAL0sqwaCsrO0EzYu5GwOw9A377dYa7ArMk64Ydft2nLktP5/D2PFACzhO3BYEWZCLDzDy5HlSOOnIkw==", + "from": "opds-fetcher-parser@github:edrlab/opds_fetcher_parser#eea41a1d50955f39d93670090e480834c26715b4", "requires": { "moment": "^2.29.1", "nanoid": "^3.1.23", "r2-lcp-js": "^1.0.30", "r2-opds-js": "^1.0.35", "r2-shared-js": "^1.0.51", - "ts-fetch": "github:panaC/ts_fetch#7f585951111aa0e9cb7fe7f99bdd927a9261cd7b" + "ts-fetch": "github:edrlab/ts_fetch#709719be762e4921b6e935f5d7105764cfaccae4" } }, "optionator": { @@ -3010,6 +8656,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "devOptional": true, "requires": { "yocto-queue": "^0.1.0" } @@ -3398,7 +9045,8 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "devOptional": true }, "resolve-from": { "version": "4.0.0", @@ -3623,29 +9271,31 @@ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "optional": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "devOptional": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "optional": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "devOptional": true, "requires": { "ansi-regex": "^5.0.1" } @@ -3732,11 +9382,12 @@ "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=" }, "ts-fetch": { - "version": "github:panaC/ts_fetch#7f585951111aa0e9cb7fe7f99bdd927a9261cd7b", - "from": "github:panaC/ts_fetch#7f585951111aa0e9cb7fe7f99bdd927a9261cd7b", + "version": "git+ssh://git@github.com/edrlab/ts_fetch.git#709719be762e4921b6e935f5d7105764cfaccae4", + "integrity": "sha512-oAbmjoqcPa4E0F0L7RYsGDy0MuYZBWfvt4cG791uZhHNrd0NCgkBGhgbTt8OIQCC4mGiXaqQH6ovGy7g3hxMVg==", + "from": "ts-fetch@github:edrlab/ts_fetch#709719be762e4921b6e935f5d7105764cfaccae4", "requires": { "fetch-cookie": "^1.0.0", - "node-fetch": "^2.6.1", + "node-fetch": "^2.6.7", "tough-cookie": "^4.0.0" }, "dependencies": { @@ -4230,6 +9881,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "devOptional": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -4272,7 +9924,8 @@ "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "devOptional": true }, "yallist": { "version": "4.0.0", @@ -4283,6 +9936,7 @@ "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "devOptional": true, "requires": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -4296,7 +9950,8 @@ "yargs-parser": { "version": "20.2.9", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "devOptional": true }, "yargs-unparser": { "version": "2.0.0", @@ -4336,7 +9991,8 @@ "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "devOptional": true } } } diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index 27772845..14740d66 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -24,7 +24,7 @@ "firebase-admin": "^9.8.0", "firebase-functions": "^3.16.0", "i18next": "^21.5.3", - "opds-fetcher-parser": "github:panaC/opds_fetcher_parser#46f59a92513c17a060d02dfceb82633bbbbc4be3", + "opds-fetcher-parser": "github:edrlab/opds_fetcher_parser#eea41a1d50955f39d93670090e480834c26715b4", "reflect-metadata": "^0.1.13" }, "devDependencies": { diff --git a/webhooks/functions/src/constants.ts b/webhooks/functions/src/constants.ts index fc35cefa..1e99ecc8 100644 --- a/webhooks/functions/src/constants.ts +++ b/webhooks/functions/src/constants.ts @@ -1,4 +1,6 @@ +export const API_BASE_URL = "https://storage.googleapis.com/audiobook_edrlab/feed.json"; + export const ALL_PUBLICATION_LIST_URL = "https://storage.googleapis.com/audiobook_edrlab/navigation/all.json"; export const SELECTION_URL = 'https://storage.googleapis.com/audiobook_edrlab/groups/popular.json'; export const SEARCH_URL = 'https://europe-west1-audiobooks-a6348.cloudfunctions.net/indexer?url=https://storage.googleapis.com/audiobook_edrlab/navigation/all.json&query={query}'; @@ -8,4 +10,4 @@ export const DEFAULT_LANGUAGE: TLang = 'fr'; export const PADDING = 5; -type TLang = 'fr' | 'en'; \ No newline at end of file +type TLang = 'fr' | 'en'; diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 376ad5d3..f2381571 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -1,6 +1,6 @@ import {conversation, Media } from "@assistant/conversation"; import * as functions from "firebase-functions"; -import {OpdsFetcher} from "opds-fetcher-parser"; +import {http as Http, AuthenticationStorage, OpdsFetcher} from "opds-fetcher-parser"; import {ok as _ok} from "assert"; // class-transformer @@ -15,7 +15,7 @@ import { selectPublication } from "./service/selectPublication"; import { testConversation } from "./conversation/test"; import { listGroups } from "./service/listGroups"; import { selectGroup } from "./service/selectGroups"; -import { ALL_PUBLICATION_LIST_URL, GENRE_LIST_URL, PADDING, SEARCH_URL, SELECTION_URL, THEMATIC_LIST_URL } from "./constants"; +import { ALL_PUBLICATION_LIST_URL, GENRE_LIST_URL, PADDING, SEARCH_URL, SELECTION_URL, THEMATIC_LIST_URL, API_BASE_URL } from "./constants"; import { i18n, t, TI18nKey } from "./translation"; import { DefaultScenes } from "@assistant/conversation/dist/conversation/handler"; @@ -99,11 +99,23 @@ app.middleware(async (conv: IConversationWithParams) => }; } + const bearerTokenRaw = conv.user.params.bearerToken; + const bearerToken = typeof bearerTokenRaw === "string" && bearerTokenRaw ? conv.user.params.bearerToken : BEARER_TOKEN_NOT_DEFINED; + + const authenticationStorage = new AuthenticationStorage(); + authenticationStorage.setAuthenticationToken({ + accessToken: bearerToken, + authenticationUrl: API_BASE_URL, + }); + const http = new Http(undefined, authenticationStorage); + + conv.di = { + opds: new OpdsFetcher(http), + }; + const locale = conv.user.locale; await i18n.changeLanguage(locale); - const bearerTokenRaw = conv.user.params.bearerToken; - const bearerToken = typeof bearerTokenRaw === "string" && bearerTokenRaw ? conv.user.params.bearerToken : BEARER_TOKEN_NOT_DEFINED; try { const data = await pull(bearerToken); @@ -132,8 +144,8 @@ app.middleware(async (conv: IConversationWithParams) => const item: TPromptItem | undefined = promptItems[0] instanceof Media ? promptItems[0] : typeof promptItems[0] === "string" - ? t(promptItems[0], typeof promptItems[1] === "object" ? promptItems[1] : undefined) - : undefined; + ? t(promptItems[0], typeof promptItems[1] === "object" ? promptItems[1] : undefined) + : undefined; ok(item, 'error.convadd'); @@ -159,7 +171,7 @@ app.handle('cancel', (conv) => { app.handle('main', (conv) => { console.log(conv.add); - + conv.add('main.welcome'); conv.scene.next.name = "home_members_lvl2"; @@ -355,8 +367,7 @@ app.handle("ask_to_resume_listening_at_last_offset", async (conv) => { const sayAudiobookTitle = async (conv: IConversationWithParams, url: string) => { - const opds = new OpdsFetcher(); - const webpub = await opds.webpubRequest(url); + const webpub = await conv.di.opds.webpubRequest(url); const title = webpub.title; if (title) { @@ -446,8 +457,8 @@ app.handle('select_publication__intent__next', async (conv) => { const url = conv.session.params.pubListUrl; ok(isValidHttpUrl(url)); - const nextUrl = await getNextLinkFromPublicationsFeed(url); - if (nextUrl && await isPublicationAvailable(nextUrl)) { + const nextUrl = await getNextLinkFromPublicationsFeed(conv.di.opds, url); + if (nextUrl && await isPublicationAvailable(conv.di.opds, nextUrl)) { conv.session.params.pubListUrl = nextUrl; conv.session.params.nextUrlCounter++; } else { @@ -484,8 +495,7 @@ app.handle("player", async (conv) => { const startIndexRaw = conv.user.params.player.current.index; const startTimeRaw = conv.user.params.player.current.time; - const opds = new OpdsFetcher(); - const webpub = await opds.webpubRequest(url); + const webpub = await conv.di.opds.webpubRequest(url); ok(webpub, 'error.webpubNotDefined'); let startIndex = (startIndexRaw && startIndexRaw > -1 && startIndexRaw <= webpub.readingOrders.length) @@ -606,8 +616,7 @@ app.handle('player__intent__remaining_time_player', async (conv) => { ok(url, 'error.urlNotValid') ok(isValidHttpUrl(url), 'error.urlNotValid'); - const opds = new OpdsFetcher(); - const webpub = await opds.webpubRequest(url); + const webpub = await conv.di.opds.webpubRequest(url); ok(webpub, 'error.webpubNotDefined'); const index = conv.user.params.player.current.index || 0; @@ -655,8 +664,7 @@ app.handle('player_toc', async (conv) => { ok(isValidHttpUrl(url), 'error.urlNotValid'); - const opds = new OpdsFetcher(); - const webpub = await opds.webpubRequest(url); + const webpub = await conv.di.opds.webpubRequest(url); const tocSliceStart = conv.session.params.tocStart; const toc = webpub.toc; @@ -686,8 +694,7 @@ app.handle('player_toc__slot__number', async (conv) => { const number = conv.intent.params?.number.resolved; ok(typeof number === "number"); - const opds = new OpdsFetcher(); - const webpub = await opds.webpubRequest(url); + const webpub = await conv.di.opds.webpubRequest(url); const toc = webpub.toc; const tocSliceStart = conv.session.params.tocStart; @@ -718,8 +725,7 @@ app.handle('player_toc__intent__next', async (conv) => { const url = conv.user.params.player.current.url; ok(isValidHttpUrl(url), 'error.urlNotValid'); - const opds = new OpdsFetcher(); - const webpub = await opds.webpubRequest(url); + const webpub = await conv.di.opds.webpubRequest(url); const toc = webpub.toc; const len = toc?.length || Infinity; diff --git a/webhooks/functions/src/service/listGroups.ts b/webhooks/functions/src/service/listGroups.ts index 24d6d332..cb014b58 100644 --- a/webhooks/functions/src/service/listGroups.ts +++ b/webhooks/functions/src/service/listGroups.ts @@ -6,7 +6,7 @@ import {t} from '../translation'; export async function listGroups(url: string, conv: IConversationWithParams, errorScene: TSdkScene = conv.scene.name) { ok(isValidHttpUrl(url), 'url not valid'); - const list = await getGroupsFromFeed(url); + const list = await getGroupsFromFeed(conv.di.opds, url); console.log('SELECTIONS: ', list); const length = list.length; diff --git a/webhooks/functions/src/service/listPublication.ts b/webhooks/functions/src/service/listPublication.ts index 5f0d3edc..b9cdc678 100644 --- a/webhooks/functions/src/service/listPublication.ts +++ b/webhooks/functions/src/service/listPublication.ts @@ -7,14 +7,14 @@ import {t} from '../translation'; export async function listPublication(url: string, conv: IConversationWithParams, errorScene: TSdkScene = conv.session?.params?.scene) { ok(isValidHttpUrl(url), 'url not valid'); - const [list, totalLength] = await getPubsFromFeed(url); - const nextUrl = await getNextLinkFromPublicationsFeed(url); + const [list, totalLength] = await getPubsFromFeed(conv.di.opds, url); + const nextUrl = await getNextLinkFromPublicationsFeed(conv.di.opds, url); console.log('PUBs: ', list); const length = list.length; if (length > 1 || conv.session.params.nextUrlCounter) { const page = conv.session.params.nextUrlCounter + 1; - const nextAvailable = !!nextUrl && await isPublicationAvailable(nextUrl); + const nextAvailable = !!nextUrl && await isPublicationAvailable(conv.di.opds, nextUrl); let text = ''; if (page === 1) { text += t('homeMembers.list.numberPublication', {length: totalLength}) + '\n'; diff --git a/webhooks/functions/src/service/selectGroups.ts b/webhooks/functions/src/service/selectGroups.ts index 2f37a1cd..ee5de1a6 100644 --- a/webhooks/functions/src/service/selectGroups.ts +++ b/webhooks/functions/src/service/selectGroups.ts @@ -4,7 +4,7 @@ import {getGroupsFromFeed, isValidHttpUrl} from '../utils'; export async function selectGroup(url: string, number: number, conv: IConversationWithParams) { ok(isValidHttpUrl(url), 'error.urlNotValid'); - const list = await getGroupsFromFeed(url); + const list = await getGroupsFromFeed(conv.di.opds, url); const group = list[number - 1]; if (!group) { console.log('NO GROUPS found !!'); diff --git a/webhooks/functions/src/service/selectPublication.ts b/webhooks/functions/src/service/selectPublication.ts index 7a465f54..b97d2e89 100644 --- a/webhooks/functions/src/service/selectPublication.ts +++ b/webhooks/functions/src/service/selectPublication.ts @@ -4,7 +4,7 @@ import {getPubsFromFeed, isValidHttpUrl} from '../utils'; export async function selectPublication(url: string, number: number, conv: IConversationWithParams) { ok(isValidHttpUrl(url), 'error.urlNotValid'); - const [list] = await getPubsFromFeed(url); + const [list] = await getPubsFromFeed(conv.di.opds, url); const pub = list[number - 1]; if (!pub) { console.log('NO PUBS found !!'); diff --git a/webhooks/functions/src/type.ts b/webhooks/functions/src/type.ts index a93dba61..8ad832c4 100644 --- a/webhooks/functions/src/type.ts +++ b/webhooks/functions/src/type.ts @@ -4,6 +4,7 @@ import { User, Scene } from "@assistant/conversation/dist/conversation/handler"; import { TI18nKey } from "./translation"; import { StorageDto } from "./model/storage.dto"; import { TSdkScene } from "./sdk"; +import { OpdsFetcher } from "opds-fetcher-parser"; export enum MediaType { Audio = 'AUDIO', @@ -29,6 +30,9 @@ interface IScene extends Scene { name: TSdkScene; } export interface IConversationWithParams extends ConversationV3 { + di: { + opds: OpdsFetcher; + }; user: IUser; scene: IScene; add: (...promptItems: TPromptItem[]) => this; @@ -42,4 +46,4 @@ export interface IConversationWithParams extends ConversationV3 { tocStart: number; } } -} \ No newline at end of file +} diff --git a/webhooks/functions/src/utils/index.ts b/webhooks/functions/src/utils/index.ts index 2d16089f..79b56e6f 100644 --- a/webhooks/functions/src/utils/index.ts +++ b/webhooks/functions/src/utils/index.ts @@ -15,12 +15,11 @@ export function isValidHttpUrl(url: string | undefined): url is string { return _url.protocol === 'http:' || _url.protocol === 'https:'; } -export async function getPubsFromFeed(url: string): Promise<[{ +export async function getPubsFromFeed(opds: OpdsFetcher, url: string): Promise<[{ title: string; author: string; webpuburl: string; }[], number]> { - const opds = new OpdsFetcher(); const feed = await opds.feedRequest(url); assert.ok(Array.isArray(feed.publications), 'no publications'); @@ -42,8 +41,7 @@ export async function getPubsFromFeed(url: string): Promise<[{ return [list, feed.metadata?.numberOfItems || list.length]; } -export async function getGroupsFromFeed(url: string) { - const opds = new OpdsFetcher(); +export async function getGroupsFromFeed(opds: OpdsFetcher, url: string) { const feed = await opds.feedRequest(url); assert.ok(Array.isArray(feed.groups), 'no groups'); @@ -60,9 +58,9 @@ export async function getGroupsFromFeed(url: string) { return list; } -export async function isPublicationAvailable(url: string): Promise { +export async function isPublicationAvailable(opds: OpdsFetcher, url: string): Promise { assert.ok(isValidHttpUrl(url)); - const [pubs] = await getPubsFromFeed(url); + const [pubs] = await getPubsFromFeed(opds, url); if (pubs.length) { return true; @@ -70,14 +68,13 @@ export async function isPublicationAvailable(url: string): Promise { return false; } -export async function getNextLinkFromPublicationsFeed(url: string): Promise { +export async function getNextLinkFromPublicationsFeed(opds: OpdsFetcher, url: string): Promise { assert.ok(isValidHttpUrl(url)); - const opds = new OpdsFetcher(); const feed = await opds.feedRequest(url); try { const nextLink = feed.links?.next[0].url; - if (nextLink && await isPublicationAvailable(nextLink)) { + if (nextLink && await isPublicationAvailable(opds, nextLink)) { return nextLink; } else { } From 59cf7430d47456dc69f90de33b34c0b5539d5193 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 24 Jan 2022 15:07:19 +0100 Subject: [PATCH 074/180] fix: update odps_fetcher_parser lib to use node14 --- webhooks/functions/package-lock.json | 5716 +------------------------- webhooks/functions/package.json | 2 +- 2 files changed, 31 insertions(+), 5687 deletions(-) diff --git a/webhooks/functions/package-lock.json b/webhooks/functions/package-lock.json index 6bf856bb..93e9f1ae 100644 --- a/webhooks/functions/package-lock.json +++ b/webhooks/functions/package-lock.json @@ -1,5638 +1,7 @@ { "name": "functions", - "lockfileVersion": 2, "requires": true, - "packages": { - "": { - "name": "functions", - "dependencies": { - "@assistant/conversation": "^3.0.0", - "class-transformer": "^0.4.0", - "class-validator": "^0.13.1", - "firebase-admin": "^9.8.0", - "firebase-functions": "^3.16.0", - "i18next": "^21.5.3", - "opds-fetcher-parser": "github:edrlab/opds_fetcher_parser#eea41a1d50955f39d93670090e480834c26715b4", - "reflect-metadata": "^0.1.13" - }, - "devDependencies": { - "@types/mocha": "^9.0.0", - "@typescript-eslint/eslint-plugin": "^5.3.1", - "@typescript-eslint/parser": "^5.3.1", - "eslint": "^8.2.0", - "eslint-config-google": "^0.14.0", - "firebase-functions-test": "^0.2.0", - "mocha": "^9.1.3", - "rimraf": "^3.0.2", - "ts-node": "^10.4.0", - "typed-i18next": "^0.1.2", - "typescript": "^4.4.4", - "typescript-eslint": "0.0.1-alpha.0" - }, - "engines": { - "node": "14" - } - }, - "node_modules/@assistant/conversation": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@assistant/conversation/-/conversation-3.8.1.tgz", - "integrity": "sha512-YEyQ33xD1VCkJP16GRdXiuG55Vklbds3yiPcGSSf0hj2dj7mprWybipEZvVA4qsgv/NHrLvXPBFTySJrUpV/7g==", - "dependencies": { - "@types/aws-lambda": "^0.0.33", - "@types/debug": "^0.0.30", - "@types/express": "^4.11.1", - "@types/node": "12.12.24", - "debug": "^3.1.0", - "google-auth-library": "^6.1.0" - }, - "engines": { - "node": ">=10.18.0" - } - }, - "node_modules/@assistant/conversation/node_modules/@types/node": { - "version": "12.12.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.24.tgz", - "integrity": "sha512-1Ciqv9pqwVtW6FsIUKSZNB82E5Cu1I2bBTj1xuIHXLe/1zYLl3956Nbhg2MzSYHVfl9/rmanjbQIb7LibfCnug==" - }, - "node_modules/@assistant/conversation/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/@assistant/conversation/node_modules/google-auth-library": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.6.tgz", - "integrity": "sha512-Q+ZjUEvLQj/lrVHF/IQwRo6p3s8Nc44Zk/DALsN+ac3T4HY/g/3rrufkgtl+nZ1TW7DNAw5cTChdVp4apUXVgQ==", - "dependencies": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@babel/runtime": { - "version": "7.16.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz", - "integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==", - "dependencies": { - "regenerator-runtime": "^0.13.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-consumer": "0.8.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@dsherret/to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@dsherret/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha1-H2R13IvZdM6gei2vOGSzF7HdMyw=", - "dev": true, - "dependencies": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.4.tgz", - "integrity": "sha512-h8Vx6MdxwWI2WM8/zREHMoqdgLNXEL4QX3MWSVMdyNJGvXVOs+6lp+m2hc3FnuMHDc4poxFNI20vCk0OmI4G0Q==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.0.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/@firebase/app-types": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.7.0.tgz", - "integrity": "sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg==" - }, - "node_modules/@firebase/auth-interop-types": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz", - "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==", - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" - } - }, - "node_modules/@firebase/component": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.7.tgz", - "integrity": "sha512-CiAHUPXh2hn/lpzMShNmfAxHNQhKQwmQUJSYMPCjf2bCCt4Z2vLGpS+UWEuNFm9Zf8LNmkS+Z+U/s4Obi5carg==", - "dependencies": { - "@firebase/util": "1.4.0", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/database": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.12.2.tgz", - "integrity": "sha512-Y1LZR1LIQM8YKMkeUPpAq3/e53hcfcXO+JEZ6vCzBeD6xRawqmpw6B5/DzePdCNNvjcqheXzSaR7T39eRZo/wA==", - "dependencies": { - "@firebase/auth-interop-types": "0.1.6", - "@firebase/component": "0.5.7", - "@firebase/logger": "0.3.0", - "@firebase/util": "1.4.0", - "faye-websocket": "0.11.4", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/database-compat": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.1.2.tgz", - "integrity": "sha512-sV32QIRSNIBj/6OYtpmPzA/SfQz1/NBZbhxg9dIhGaSt9e5HaMxXRuz2lImudX0Sd/v8DKdExrxa++K6rKrRtA==", - "dependencies": { - "@firebase/component": "0.5.7", - "@firebase/database": "0.12.2", - "@firebase/database-types": "0.9.1", - "@firebase/logger": "0.3.0", - "@firebase/util": "1.4.0", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/database-compat/node_modules/@firebase/database-types": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.9.1.tgz", - "integrity": "sha512-RUixK/YrbpxbfdE+nYP0wMcEsz1xPTnafP0q3UlSS/+fW744OITKtR1J0cMRaXbvY7EH0wUVTNVkrtgxYY8IgQ==", - "dependencies": { - "@firebase/app-types": "0.7.0", - "@firebase/util": "1.4.0" - } - }, - "node_modules/@firebase/database-types": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.7.3.tgz", - "integrity": "sha512-dSOJmhKQ0nL8O4EQMRNGpSExWCXeHtH57gGg0BfNAdWcKhC8/4Y+qfKLfWXzyHvrSecpLmO0SmAi/iK2D5fp5A==", - "dependencies": { - "@firebase/app-types": "0.6.3" - } - }, - "node_modules/@firebase/database-types/node_modules/@firebase/app-types": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.6.3.tgz", - "integrity": "sha512-/M13DPPati7FQHEQ9Minjk1HGLm/4K4gs9bR4rzLCWJg64yGtVC0zNg9gDpkw9yc2cvol/mNFxqTtd4geGrwdw==" - }, - "node_modules/@firebase/logger": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.3.0.tgz", - "integrity": "sha512-7oQ+TctqekfgZImWkKuda50JZfkmAKMgh5qY4aR4pwRyqZXuJXN1H/BKkHvN1y0S4XWtF0f/wiCLKHhyi1ppPA==", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/util": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.4.0.tgz", - "integrity": "sha512-Qn58d+DVi1nGn0bA9RV89zkz0zcbt6aUcRdyiuub/SuEvjKYstWmHcHwh1C0qmE1wPf9a3a+AuaRtduaGaRT7A==", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/@google-cloud/common": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.7.4.tgz", - "integrity": "sha512-JO4a8l/N6fkHZ+vWgNYgcNoZh1/m6kqv8F7+NpBkGqs7NzUtkmE9WdvHaNUwAOm1mIqbuX2wXKNfAZfqZr+vMg==", - "optional": true, - "dependencies": { - "@google-cloud/projectify": "^2.0.0", - "@google-cloud/promisify": "^2.0.0", - "arrify": "^2.0.1", - "duplexify": "^4.1.1", - "ent": "^2.2.0", - "extend": "^3.0.2", - "google-auth-library": "^7.9.2", - "retry-request": "^4.2.2", - "teeny-request": "^7.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@google-cloud/firestore": { - "version": "4.15.1", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.15.1.tgz", - "integrity": "sha512-2PWsCkEF1W02QbghSeRsNdYKN1qavrHBP3m72gPDMHQSYrGULOaTi7fSJquQmAtc4iPVB2/x6h80rdLHTATQtA==", - "optional": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "functional-red-black-tree": "^1.0.1", - "google-gax": "^2.24.1", - "protobufjs": "^6.8.6" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@google-cloud/paginator": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.6.tgz", - "integrity": "sha512-XCTm/GfQIlc1ZxpNtTSs/mnZxC2cePNhxU3X8EzHXKIJ2JFncmJj2Fcd2IP+gbmZaSZnY0juFxbUCkIeuu/2eQ==", - "optional": true, - "dependencies": { - "arrify": "^2.0.0", - "extend": "^3.0.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@google-cloud/projectify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.1.1.tgz", - "integrity": "sha512-+rssMZHnlh0twl122gXY4/aCrk0G1acBqkHFfYddtsqpYXGxA29nj9V5V9SfC+GyOG00l650f6lG9KL+EpFEWQ==", - "optional": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@google-cloud/promisify": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.4.tgz", - "integrity": "sha512-j8yRSSqswWi1QqUGKVEKOG03Q7qOoZP6/h2zN2YO+F5h2+DHU0bSrHCK9Y7lo2DI9fBd8qGAw795sf+3Jva4yA==", - "optional": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@google-cloud/storage": { - "version": "5.15.3", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.15.3.tgz", - "integrity": "sha512-a2Y+mvfbzznWorQiv6c+qdPDlBpe47tikV8tpQSnvYXz1Ed/rjin41k2nKUQUcAPGHtYeTzGfKnCNKC+lv8qRg==", - "optional": true, - "dependencies": { - "@google-cloud/common": "^3.7.4", - "@google-cloud/paginator": "^3.0.0", - "@google-cloud/promisify": "^2.0.0", - "arrify": "^2.0.0", - "async-retry": "^1.3.1", - "compressible": "^2.0.12", - "date-and-time": "^2.0.0", - "duplexify": "^4.0.0", - "extend": "^3.0.2", - "gcs-resumable-upload": "^3.3.0", - "get-stream": "^6.0.0", - "hash-stream-validation": "^0.2.2", - "mime": "^2.2.0", - "mime-types": "^2.0.8", - "p-limit": "^3.0.1", - "pumpify": "^2.0.0", - "snakeize": "^0.1.0", - "stream-events": "^1.0.1", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@grpc/grpc-js": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.4.2.tgz", - "integrity": "sha512-aUN6oGk9un8rfYWz73nQgFxPCYJQYd8LpIGguZHBsNduBMyqG6EWANrsVBuTG+nl/l4dKb3x+qi1l9+oxDxqGg==", - "optional": true, - "dependencies": { - "@grpc/proto-loader": "^0.6.4", - "@types/node": ">=12.12.47" - }, - "engines": { - "node": "^8.13.0 || >=10.10.0" - } - }, - "node_modules/@grpc/proto-loader": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.6.tgz", - "integrity": "sha512-cdMaPZ8AiFz6ua6PUbP+LKbhwJbFXnrQ/mlnKGUyzDUZ3wp7vPLksnmLCBX6SHgSmjX7CbNVNLFYD5GmmjO4GQ==", - "optional": true, - "dependencies": { - "@types/long": "^4.0.1", - "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", - "protobufjs": "^6.10.0", - "yargs": "^16.1.1" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.6.0.tgz", - "integrity": "sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@panva/asn1.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", - "integrity": "sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=", - "optional": true - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "optional": true - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "optional": true - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=", - "optional": true - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "optional": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=", - "optional": true - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=", - "optional": true - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=", - "optional": true - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=", - "optional": true - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", - "optional": true - }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "optional": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", - "dev": true - }, - "node_modules/@types/aws-lambda": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-0.0.33.tgz", - "integrity": "sha512-p13MzAb/1ZJK1h0jDhRjdFqlRHC44HAOS7qYuVpn7NnFDv8UdNbRjExfhK69syvI9IoIR4NN4dRGjpVDsN6tEQ==" - }, - "node_modules/@types/body-parser": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz", - "integrity": "sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/cors": { - "version": "2.8.12", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", - "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" - }, - "node_modules/@types/debug": { - "version": "0.0.30", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-0.0.30.tgz", - "integrity": "sha512-orGL5LXERPYsLov6CWs3Fh6203+dXzJkR7OnddIr2514Hsecwc8xRpzCapshBbKFImCsvS/mk6+FWiN5LyZJAQ==" - }, - "node_modules/@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-jwt": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@types/express-jwt/-/express-jwt-0.0.42.tgz", - "integrity": "sha512-WszgUddvM1t5dPpJ3LhWNH8kfNN8GPIBrAGxgIYXVCEGx6Bx4A036aAuf/r5WH9DIEdlmp7gHOYvSM6U87B0ag==", - "dependencies": { - "@types/express": "*", - "@types/express-unless": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.24", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.24.tgz", - "integrity": "sha512-3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "node_modules/@types/express-unless": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.2.tgz", - "integrity": "sha512-Q74UyYRX/zIgl1HSp9tUX2PlG8glkVm+59r7aK4KGKzC5jqKIOX6rrVLRQrzpZUQ84VukHtRoeAuon2nIssHPQ==", - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/fs-extra": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz", - "integrity": "sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true - }, - "node_modules/@types/lodash": { - "version": "4.14.176", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.176.tgz", - "integrity": "sha512-xZmuPTa3rlZoIbtDUyJKZQimJV3bxCmzMIO2c9Pz9afyDro6kr7R79GwcB6mRhuoPmV2p1Vb66WOJH7F886WKQ==", - "dev": true - }, - "node_modules/@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==", - "optional": true - }, - "node_modules/@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" - }, - "node_modules/@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true - }, - "node_modules/@types/mocha": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.0.0.tgz", - "integrity": "sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==", - "dev": true - }, - "node_modules/@types/node": { - "version": "16.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz", - "integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==" - }, - "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" - }, - "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" - }, - "node_modules/@types/serve-static": { - "version": "1.13.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", - "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/validator": { - "version": "13.6.6", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.6.6.tgz", - "integrity": "sha512-+qogUELb4gMhrMjSh/seKmGVvN+uQLfyqJAqYRWqVHsvBsUO2xDBCL8CJ/ZSukbd8vXaoYbpIssAmfLEzzBHEw==" - }, - "node_modules/@types/xmldom": { - "version": "0.1.31", - "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.31.tgz", - "integrity": "sha512-bVy7s0nvaR5D1mT1a8ZkByHWNOGb6Vn4yi5TWhEdmyKlAG+08SA7Md6+jH+tYmMLueAwNeWvHHpeKrr6S4c4BA==" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.3.1.tgz", - "integrity": "sha512-cFImaoIr5Ojj358xI/SDhjog57OK2NqlpxwdcgyxDA3bJlZcJq5CPzUXtpD7CxI2Hm6ATU7w5fQnnkVnmwpHqw==", - "dev": true, - "dependencies": { - "@typescript-eslint/experimental-utils": "5.3.1", - "@typescript-eslint/scope-manager": "5.3.1", - "debug": "^4.3.2", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.2.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.3.1.tgz", - "integrity": "sha512-RgFn5asjZ5daUhbK5Sp0peq0SSMytqcrkNfU4pnDma2D8P3ElZ6JbYjY8IMSFfZAJ0f3x3tnO3vXHweYg0g59w==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.3.1", - "@typescript-eslint/types": "5.3.1", - "@typescript-eslint/typescript-estree": "5.3.1", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.3.1.tgz", - "integrity": "sha512-TD+ONlx5c+Qhk21x9gsJAMRohWAUMavSOmJgv3JGy9dgPhuBd5Wok0lmMClZDyJNLLZK1JRKiATzCKZNUmoyfw==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.3.1", - "@typescript-eslint/types": "5.3.1", - "@typescript-eslint/typescript-estree": "5.3.1", - "debug": "^4.3.2" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.3.1.tgz", - "integrity": "sha512-XksFVBgAq0Y9H40BDbuPOTUIp7dn4u8oOuhcgGq7EoDP50eqcafkMVGrypyVGvDYHzjhdUCUwuwVUK4JhkMAMg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.3.1", - "@typescript-eslint/visitor-keys": "5.3.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.3.1.tgz", - "integrity": "sha512-bG7HeBLolxKHtdHG54Uac750eXuQQPpdJfCYuw4ZI3bZ7+GgKClMWM8jExBtp7NSP4m8PmLRM8+lhzkYnSmSxQ==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.3.1.tgz", - "integrity": "sha512-PwFbh/PKDVo/Wct6N3w+E4rLZxUDgsoII/GrWM2A62ETOzJd4M6s0Mu7w4CWsZraTbaC5UQI+dLeyOIFF1PquQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.3.1", - "@typescript-eslint/visitor-keys": "5.3.1", - "debug": "^4.3.2", - "globby": "^11.0.4", - "is-glob": "^4.0.3", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.3.1.tgz", - "integrity": "sha512-3cHUzUuVTuNHx0Gjjt5pEHa87+lzyqOiHXy/Gz+SJOCW1mpw9xQHIIEwnKn+Thph1mgWyZ90nboOcSuZr/jTTQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.3.1", - "eslint-visitor-keys": "^3.0.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "devOptional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "devOptional": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-differ": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", - "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "engines": { - "node": ">=8" - } - }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/async-retry": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", - "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", - "optional": true, - "dependencies": { - "retry": "0.13.1" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/big-integer": { - "version": "1.6.51", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", - "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", - "engines": { - "node": "*" - } - }, - "node_modules/binary": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", - "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", - "dependencies": { - "buffers": "~0.1.1", - "chainsaw": "~0.1.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "node_modules/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "dependencies": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "engines": { - "node": "*" - } - }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "node_modules/buffer-indexof-polyfill": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", - "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/buffers": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", - "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", - "engines": { - "node": ">=0.2.0" - } - }, - "node_modules/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "node_modules/chainsaw": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", - "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", - "dependencies": { - "traverse": ">=0.3.0 <0.4" - }, - "engines": { - "node": "*" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/class-transformer": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.4.0.tgz", - "integrity": "sha512-ETWD/H2TbWbKEi7m9N4Km5+cw1hNcqJSxlSYhsLsNjQzWWiZIYA1zafxpK9PwVfaZ6AqR5rrjPVUBGESm5tQUA==" - }, - "node_modules/class-validator": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.13.1.tgz", - "integrity": "sha512-zWIeYFhUitvAHBwNhDdCRK09hWx+P0HUwFE8US8/CxFpMVzkUK8RJl7yOIE+BVu2lxyPNgeOaFv78tLE47jBIg==", - "dependencies": { - "@types/validator": "^13.1.3", - "libphonenumber-js": "^1.9.7", - "validator": "^13.5.2" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "devOptional": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/code-block-writer": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-10.1.1.tgz", - "integrity": "sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==", - "dev": true - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "devOptional": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "devOptional": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", - "dev": true - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "optional": true, - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "optional": true, - "dependencies": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "dependencies": { - "safe-buffer": "5.1.2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-disposition/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/date-and-time": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-2.0.1.tgz", - "integrity": "sha512-O7Xe5dLaqvY/aF/MFWArsAM1J4j7w1CSZlPCX9uHgmb+6SbkPd8Q4YOvfvH/cZGvFlJFfHOZKxQtmMUOoZhc/w==", - "optional": true - }, - "node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "node_modules/dicer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", - "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", - "dependencies": { - "streamsearch": "0.1.2" - }, - "engines": { - "node": ">=4.5.0" - } - }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "optional": true, - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dependencies": { - "readable-stream": "^2.0.2" - } - }, - "node_modules/duplexer2/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/duplexer2/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/duplexer2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "optional": true, - "dependencies": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "devOptional": true - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "optional": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", - "optional": true - }, - "node_modules/err-code": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", - "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=" - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "devOptional": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.2.0.tgz", - "integrity": "sha512-erw7XmM+CLxTOickrimJ1SiF55jiNlVSp2qqm0NuBWPtHYQCegD5ZMaW0c3i5ytPqL+SSLaCxdvQXFPLJn+ABw==", - "dev": true, - "dependencies": { - "@eslint/eslintrc": "^1.0.4", - "@humanwhocodes/config-array": "^0.6.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^6.0.0", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.0.0", - "espree": "^9.0.0", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.2.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-google": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", - "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "eslint": ">=5.16.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", - "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-6.0.0.tgz", - "integrity": "sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/eslint/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/espree": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.0.0.tgz", - "integrity": "sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ==", - "dev": true, - "dependencies": { - "acorn": "^8.5.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.0.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "dependencies": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/express/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "node_modules/fast-text-encoding": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", - "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==" - }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/fetch-cookie": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-1.0.0.tgz", - "integrity": "sha512-SWcAhkDe4yVBFtwRqJNmot6k1XjjzI7tw3aRHepxXrK6FQp6obBhqcnsdm2aNUzrtE71607crNAYodtKMq3TjA==", - "dependencies": { - "tough-cookie": "^2.3.3 || ^3.0.1 || ^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/file-js": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/file-js/-/file-js-0.3.0.tgz", - "integrity": "sha1-+rRr94I0bJKUSZ8fDSrQfYOPJdE=", - "dependencies": { - "bluebird": "^3.4.7", - "minimatch": "^3.0.3", - "proper-lockfile": "^1.2.0" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "node_modules/filehound": { - "version": "1.17.5", - "resolved": "https://registry.npmjs.org/filehound/-/filehound-1.17.5.tgz", - "integrity": "sha512-BsNTM3xoscYKgv0quE9RWPVhu5ZTb7BNu3H/IbZQbOfQeA7ZyOV/hIYfo60H3Jhorw/J5vbg59KHS1UCHt4FAw==", - "dependencies": { - "bluebird": "^3.7.2", - "file-js": "0.3.0", - "lodash": "^4.17.21", - "minimatch": "^3.0.4", - "moment": "^2.29.1", - "unit-compare": "^1.0.1" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/firebase-admin": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.12.0.tgz", - "integrity": "sha512-AtA7OH5RbIFGoc0gZOQgaYC6cdjdhZv4w3XgWoupkPKO1HY+0GzixOuXDa75kFeoVyhIyo4PkLg/GAC1dC1P6w==", - "dependencies": { - "@firebase/database-compat": "^0.1.1", - "@firebase/database-types": "^0.7.2", - "@types/node": ">=12.12.47", - "dicer": "^0.3.0", - "jsonwebtoken": "^8.5.1", - "jwks-rsa": "^2.0.2", - "node-forge": "^0.10.0" - }, - "engines": { - "node": ">=10.13.0" - }, - "optionalDependencies": { - "@google-cloud/firestore": "^4.5.0", - "@google-cloud/storage": "^5.3.0" - } - }, - "node_modules/firebase-functions": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.16.0.tgz", - "integrity": "sha512-6ISOn0JckMtpA3aJ/+wCCGhThUhBUrpZD+tSkUeolx0Vr+NoYFXA0+2YzJZa/A2MDU8gotPzUtnauLSEQvfClQ==", - "dependencies": { - "@types/cors": "^2.8.5", - "@types/express": "4.17.3", - "cors": "^2.8.5", - "express": "^4.17.1", - "lodash": "^4.17.14" - }, - "engines": { - "node": "^8.13.0 || >=10.10.0" - }, - "peerDependencies": { - "firebase-admin": "^8.0.0 || ^9.0.0 || ^10.0.0" - } - }, - "node_modules/firebase-functions-test": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/firebase-functions-test/-/firebase-functions-test-0.2.3.tgz", - "integrity": "sha512-zYX0QTm53wCazuej7O0xqbHl90r/v1PTXt/hwa0jo1YF8nDM+iBKnLDlkIoW66MDd0R6aGg4BvKzTTdJpvigUA==", - "dev": true, - "dependencies": { - "@types/lodash": "^4.14.104", - "lodash": "^4.17.5" - }, - "engines": { - "node": ">=8.0.0" - }, - "peerDependencies": { - "firebase-admin": ">=6.0.0", - "firebase-functions": ">=2.0.0" - } - }, - "node_modules/firebase-functions/node_modules/@types/express": { - "version": "4.17.3", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.3.tgz", - "integrity": "sha512-I8cGRJj3pyOLs/HndoP+25vOqhqWkAZsWMEmq1qXy/b/M3ppufecUwaK2/TVDVxcV61/iSdhykUjQQ2DLSrTdg==", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "*", - "@types/serve-static": "*" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/flatted": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", - "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", - "dev": true - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", - "dependencies": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - }, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/fstream/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "devOptional": true - }, - "node_modules/gaxios": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.2.tgz", - "integrity": "sha512-T+ap6GM6UZ0c4E6yb1y/hy2UB6hTrqhglp3XfmU9qbLCGRYhLVV5aRPpC4EmoG8N8zOnkYCgoBz+ScvGAARY6Q==", - "dependencies": { - "abort-controller": "^3.0.0", - "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/gcp-metadata": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.1.tgz", - "integrity": "sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==", - "dependencies": { - "gaxios": "^4.0.0", - "json-bigint": "^1.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/gcs-resumable-upload": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/gcs-resumable-upload/-/gcs-resumable-upload-3.3.1.tgz", - "integrity": "sha512-WyC0i4VkslIdrdmeM5PNuGzANALLXTG5RoHb08OE30gYT+FEvCDPiA8KOjV2s1wOu9ngEW4+IuzBjtP/ni7UdQ==", - "optional": true, - "dependencies": { - "abort-controller": "^3.0.0", - "configstore": "^5.0.0", - "extend": "^3.0.2", - "gaxios": "^4.0.0", - "google-auth-library": "^7.0.0", - "pumpify": "^2.0.0", - "stream-events": "^1.0.4" - }, - "bin": { - "gcs-upload": "build/src/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "devOptional": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "optional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dependencies": { - "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" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/google-auth-library": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.10.1.tgz", - "integrity": "sha512-nQxgM1ZopUMcpMnu95kOSzI+9tJl4YDOZJomSTBGlRLpxfBopdwto7WvzoI87HuN0nQqVETgOsHi/C/po1rppA==", - "optional": true, - "dependencies": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/google-gax": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.28.0.tgz", - "integrity": "sha512-kuqc8a4+CTCMBcF3tlOL7Sa74JWkTzcZxatAQTCVK35WToXkHnJ0qncFOJuegUv3EbV9IQY4j/+NZdFLv+lbTA==", - "optional": true, - "dependencies": { - "@grpc/grpc-js": "~1.4.0", - "@grpc/proto-loader": "^0.6.1", - "@types/long": "^4.0.0", - "abort-controller": "^3.0.0", - "duplexify": "^4.0.0", - "fast-text-encoding": "^1.0.3", - "google-auth-library": "^7.6.1", - "is-stream-ended": "^0.1.4", - "node-fetch": "^2.6.1", - "object-hash": "^2.1.1", - "proto3-json-serializer": "^0.1.1", - "protobufjs": "6.11.2", - "retry-request": "^4.0.0" - }, - "bin": { - "compileProtos": "build/tools/compileProtos.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/google-p12-pem": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.2.tgz", - "integrity": "sha512-tjf3IQIt7tWCDsa0ofDQ1qqSCNzahXDxdAGJDbruWqu3eCg5CKLYKN+hi0s6lfvzYZ1GDVr+oDF9OOWlDSdf0A==", - "dependencies": { - "node-forge": "^0.10.0" - }, - "bin": { - "gp12-pem": "build/src/bin/gp12-pem.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" - }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "engines": { - "node": ">=4.x" - } - }, - "node_modules/gtoken": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.3.1.tgz", - "integrity": "sha512-yqOREjzLHcbzz1UrQoxhBtpk8KjrVhuqPE7od1K2uhyxG2BHjKZetlbLw/SPZak/QqTIQW+addS+EcjqQsZbwQ==", - "dependencies": { - "gaxios": "^4.0.0", - "google-p12-pem": "^3.0.3", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/hash-stream-validation": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.4.tgz", - "integrity": "sha512-Gjzu0Xn7IagXVkSu9cSFuK1fqzwtLwFhNhVL8IFJijRNMgUttFbBSIAzKuSIrsFMO1+g1RlsoN49zPIbwPDMGQ==", - "optional": true - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/http-errors/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "node_modules/http-parser-js": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", - "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==" - }, - "node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "optional": true, - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/i18next": { - "version": "21.5.3", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.5.3.tgz", - "integrity": "sha512-9R8127a0/N5okiD7eeo6XBPQsHgHsLr1GdQEa35Pcw305ArC9KZDLs9kbgdn3xuVUNYlVu8+gWzz73eVkna0gA==", - "dependencies": { - "@babel/runtime": "^7.12.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz", - "integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/image-size": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.0.tgz", - "integrity": "sha512-JLJ6OwBfO1KcA+TvJT+v8gbE6iWbj24LyDNFgFEN0lzegn6cC6a/p3NIDaepMsJjQjlUWqIC7wJv8lBFxPNjcw==", - "dependencies": { - "queue": "6.0.2" - }, - "bin": { - "image-size": "bin/image-size.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "devOptional": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "dependencies": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "devOptional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "dependencies": { - "is-unc-path": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-stream-ended": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", - "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==", - "optional": true - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "node_modules/is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "dependencies": { - "unc-path-regex": "^0.1.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "node_modules/jose": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.5.tgz", - "integrity": "sha512-BAiDNeDKTMgk4tvD0BbxJ8xHEHBZgpeRZ1zGPPsitSyMgjoMWiLGYAE7H7NpP5h0lPppQajQs871E8NHUrzVPA==", - "dependencies": { - "@panva/asn1.js": "^1.0.0" - }, - "engines": { - "node": ">=10.13.0 < 13 || >=13.7.0" - }, - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "node_modules/json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "dependencies": { - "bignumber.js": "^9.0.0" - } - }, - "node_modules/json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonwebtoken": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", - "dependencies": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=4", - "npm": ">=1.4.28" - } - }, - "node_modules/jsonwebtoken/node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jsonwebtoken/node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "dependencies": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jsonwebtoken/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "node_modules/jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jwks-rsa": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.0.5.tgz", - "integrity": "sha512-fliHfsiBRzEU0nXzSvwnh0hynzGB0WihF+CinKbSRlaqRxbqqKf2xbBPgwc8mzf18/WgwlG8e5eTpfSTBcU4DQ==", - "dependencies": { - "@types/express-jwt": "0.0.42", - "debug": "^4.3.2", - "jose": "^2.0.5", - "limiter": "^1.1.5", - "lru-memoizer": "^2.1.4" - }, - "engines": { - "node": ">=10 < 13 || >=14" - } - }, - "node_modules/jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "dependencies": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/libphonenumber-js": { - "version": "1.9.42", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.9.42.tgz", - "integrity": "sha512-UBtU0ylpZPKPT8NLIyQJWj/DToMFxmo3Fm5m6qDc0LATvf0SY0qUhaurCEvukAB9Fo+Ia2Anjzqwoupaa64fXg==" - }, - "node_modules/limiter": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", - "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" - }, - "node_modules/listenercount": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", - "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=" - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", - "optional": true - }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" - }, - "node_modules/lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" - }, - "node_modules/lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" - }, - "node_modules/lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" - }, - "node_modules/lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" - }, - "node_modules/lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/loglevel": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz", - "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==", - "dev": true, - "engines": { - "node": ">= 0.6.0" - }, - "funding": { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/loglevel" - } - }, - "node_modules/loglevel-plugin-prefix": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", - "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", - "dev": true - }, - "node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "optional": true - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/lru-memoizer": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.1.4.tgz", - "integrity": "sha512-IXAq50s4qwrOBrXJklY+KhgZF+5y98PDaNo0gi/v2KQBFLyWr+JyFvijZXkGKjQj/h9c0OwoE+JZbwUXce76hQ==", - "dependencies": { - "lodash.clonedeep": "^4.5.0", - "lru-cache": "~4.0.0" - } - }, - "node_modules/lru-memoizer/node_modules/lru-cache": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", - "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=", - "dependencies": { - "pseudomap": "^1.0.1", - "yallist": "^2.0.0" - } - }, - "node_modules/lru-memoizer/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "optional": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", - "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", - "optional": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", - "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", - "dependencies": { - "mime-db": "1.50.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mocha": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz", - "integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==", - "dev": true, - "dependencies": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.2", - "debug": "4.3.2", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.7", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "nanoid": "3.1.25", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.1.5", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/mocha/node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "dependencies": { - "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" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mocha/node_modules/nanoid": { - "version": "3.1.25", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", - "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/mocha/node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/multimatch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz", - "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==", - "dev": true, - "dependencies": { - "@types/minimatch": "^3.0.3", - "array-differ": "^3.0.0", - "array-union": "^2.1.0", - "arrify": "^2.0.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nanoid": { - "version": "3.1.30", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz", - "integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node_modules/negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/node-stream-zip": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.15.0.tgz", - "integrity": "sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw==", - "engines": { - "node": ">=0.12.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/antelle" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "engines": { - "node": "*" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", - "optional": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/opds-fetcher-parser": { - "version": "0.1.0", - "resolved": "git+ssh://git@github.com/edrlab/opds_fetcher_parser.git#eea41a1d50955f39d93670090e480834c26715b4", - "integrity": "sha512-tAgaTwyAL0sqwaCsrO0EzYu5GwOw9A377dYa7ArMk64Ydft2nLktP5/D2PFACzhO3BYEWZCLDzDy5HlSOOnIkw==", - "license": "BSD-3-Clause", - "dependencies": { - "moment": "^2.29.1", - "nanoid": "^3.1.23", - "r2-lcp-js": "^1.0.30", - "r2-opds-js": "^1.0.35", - "r2-shared-js": "^1.0.51", - "ts-fetch": "github:edrlab/ts_fetch#709719be762e4921b6e935f5d7105764cfaccae4" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "devOptional": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/proper-lockfile": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-1.2.0.tgz", - "integrity": "sha1-zv9d2J0+XxD7deHo52vHWAGlnDQ=", - "dependencies": { - "err-code": "^1.0.0", - "extend": "^3.0.0", - "graceful-fs": "^4.1.2", - "retry": "^0.10.0" - } - }, - "node_modules/proper-lockfile/node_modules/retry": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", - "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", - "engines": { - "node": "*" - } - }, - "node_modules/proto3-json-serializer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-0.1.5.tgz", - "integrity": "sha512-G395jcZkgNXNeS+6FGqd09TsXeoCs9wmBWByDiwFy7Yd7HD8pyfyvf6q+rGh7PhT4AshRpG4NowzoKYUtkNjKg==", - "optional": true - }, - "node_modules/protobufjs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", - "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "optional": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/pumpify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", - "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", - "optional": true, - "dependencies": { - "duplexify": "^4.1.1", - "inherits": "^2.0.3", - "pump": "^3.0.0" - } - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/queue": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", - "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", - "dependencies": { - "inherits": "~2.0.3" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/r2-lcp-js": { - "version": "1.0.33", - "resolved": "https://registry.npmjs.org/r2-lcp-js/-/r2-lcp-js-1.0.33.tgz", - "integrity": "sha512-WNPVjHd1v8appnAqGZ/B8DlRm4k0JdixOc1TSwF+FSrjcBidG+CWijozFEBdPF+DT6FQAZcBc91B+Oc4qw3OJg==", - "dependencies": { - "bindings": "^1.5.0", - "debug": "^4.3.2", - "moment": "^2.29.1", - "r2-utils-js": "^1.0.27", - "request": "^2.88.2", - "request-promise-native": "^1.0.9", - "ta-json-x": "^2.5.3", - "tslib": "^2.3.1", - "urijs": "^1.19.7" - }, - "engines": { - "node": ">=14", - "npm": ">=6", - "yarn": ">=1.0" - } - }, - "node_modules/r2-opds-js": { - "version": "1.0.38", - "resolved": "https://registry.npmjs.org/r2-opds-js/-/r2-opds-js-1.0.38.tgz", - "integrity": "sha512-yZB1BFmfrxgvIIe1t+p7nWrMcSS+8ge9NJIDaPe1Zq6rHpC8IlBy5HvdCgGN6pX7Ix1u3VbI1zy/KxVFUPzAsg==", - "dependencies": { - "debug": "^4.3.2", - "r2-lcp-js": "^1.0.33", - "r2-shared-js": "^1.0.53", - "r2-utils-js": "^1.0.27", - "ta-json-x": "^2.5.3", - "tslib": "^2.3.1", - "xmldom": "^0.6.0" - }, - "engines": { - "node": ">=16", - "npm": ">=8" - } - }, - "node_modules/r2-shared-js": { - "version": "1.0.53", - "resolved": "https://registry.npmjs.org/r2-shared-js/-/r2-shared-js-1.0.53.tgz", - "integrity": "sha512-1LyAd5Ebhyfe2gRFg8wE0wS9yK+bYDBfRZLpCxCX5O3JNdSwuVwLAff6qLhk7ExagifFRB4ZUNMpW1n3zEUi+Q==", - "dependencies": { - "debug": "^4.3.2", - "fast-deep-equal": "^3.1.3", - "image-size": "^1.0.0", - "mime-types": "^2.1.33", - "moment": "^2.29.1", - "r2-lcp-js": "^1.0.33", - "r2-utils-js": "^1.0.27", - "slugify": "^1.6.1", - "ta-json-x": "^2.5.3", - "tslib": "^2.3.1", - "xmldom": "^0.6.0", - "xpath": "^0.0.32", - "yazl": "^2.5.1" - }, - "bin": { - "r2-shared-js-cli": "dist/es6-es2015/src/_utils/cli.js" - }, - "engines": { - "node": ">=14", - "npm": ">=6", - "yarn": ">=1.0" - } - }, - "node_modules/r2-utils-js": { - "version": "1.0.27", - "resolved": "https://registry.npmjs.org/r2-utils-js/-/r2-utils-js-1.0.27.tgz", - "integrity": "sha512-uZ0P/JBKY16JAsL5FwH/r2k+9Jq30i7IdWxsa26mki/2DHALE4lv+Qs80kU68pHWKXS+eeriyCkCTCmI32TJTw==", - "dependencies": { - "@types/xmldom": "^0.1.31", - "debug": "^4.3.2", - "filehound": "^1.17.5", - "node-stream-zip": "^1.15.0", - "reflect-metadata": "^0.1.13", - "request": "^2.88.2", - "request-promise-native": "^1.0.9", - "ta-json-x": "^2.5.3", - "tslib": "^2.3.1", - "unzipper": "^0.10.11", - "xpath": "^0.0.32", - "yauzl": "^2.10.0", - "yazl": "^2.5.1" - }, - "engines": { - "node": ">=14", - "npm": ">=6", - "yarn": ">=1.0" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "optional": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" - }, - "node_modules/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dependencies": { - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", - "dependencies": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "engines": { - "node": ">=0.12.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "devOptional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "optional": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/retry-request": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.2.2.tgz", - "integrity": "sha512-xA93uxUD/rogV7BV59agW/JHPGXeREMWiZc9jhcwY4YdZ7QOtC7qbomYg0n4wyk2lJhggjvKvhNX8wln/Aldhg==", - "optional": true, - "dependencies": { - "debug": "^4.1.1", - "extend": "^3.0.2" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "optional": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dependencies": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/send/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "node_modules/setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "optional": true - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slugify": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.2.tgz", - "integrity": "sha512-XMtI8qD84LwCpthLMBHlIhcrj10cgA+U/Ot8G6FD6uFuWZtMfKK75JO7l81nzpFJsPlsW6LT+VKqWQJW3+6New==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/snakeize": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/snakeize/-/snakeize-0.1.0.tgz", - "integrity": "sha1-EMCI2LWOsHazIpu1oE4jLOEmQi0=", - "optional": true - }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stream-events": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", - "optional": true, - "dependencies": { - "stubs": "^3.0.0" - } - }, - "node_modules/stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "optional": true - }, - "node_modules/streamsearch": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", - "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "optional": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "devOptional": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "devOptional": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/stubs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=", - "optional": true - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ta-json-x": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ta-json-x/-/ta-json-x-2.5.3.tgz", - "integrity": "sha512-zhn9oZJVUOj73/WmLFoLszp8+zl8RZAU995dTQWhZK/2eSvFiz2eZ3nN6Kk7B6lRg2GUWnW1v3S3IUhFNbwYQA==", - "dependencies": { - "reflect-metadata": "^0.1.13" - } - }, - "node_modules/teeny-request": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.1.3.tgz", - "integrity": "sha512-Ew3aoFzgQEatLA5OBIjdr1DWJUaC1xardG+qbPPo5k/y/3fMwXLxpjh5UB5dVfElktLaQbbMs80chkz53ByvSg==", - "optional": true, - "dependencies": { - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.1", - "stream-events": "^1.0.5", - "uuid": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" - }, - "node_modules/traverse": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", - "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", - "engines": { - "node": "*" - } - }, - "node_modules/ts-fetch": { - "version": "0.1.0", - "resolved": "git+ssh://git@github.com/edrlab/ts_fetch.git#709719be762e4921b6e935f5d7105764cfaccae4", - "integrity": "sha512-oAbmjoqcPa4E0F0L7RYsGDy0MuYZBWfvt4cG791uZhHNrd0NCgkBGhgbTt8OIQCC4mGiXaqQH6ovGy7g3hxMVg==", - "license": "BSD-3-Clause", - "dependencies": { - "fetch-cookie": "^1.0.0", - "node-fetch": "^2.6.7", - "tough-cookie": "^4.0.0" - } - }, - "node_modules/ts-fetch/node_modules/tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ts-morph": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-4.3.3.tgz", - "integrity": "sha512-yauxRJM4Vo+KvpJFgL4Mp9PtFjwZVrt54eP3RkLIXnaaAY5TGVHTLqN2OnLGwf6YjyqkDLAKprZVOUTvVEz6ZQ==", - "dev": true, - "dependencies": { - "@dsherret/to-absolute-glob": "^2.0.2", - "chalk": "^2.4.2", - "code-block-writer": "^10.0.0", - "fs-extra": "^8.1.0", - "glob-parent": "^5.1.0", - "globby": "^10.0.1", - "is-negated-glob": "^1.0.0", - "multimatch": "^4.0.0", - "typescript": "3.0.1 - 3.6.4" - } - }, - "node_modules/ts-morph/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ts-morph/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ts-morph/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/ts-morph/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/ts-morph/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/ts-morph/node_modules/globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-morph/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ts-morph/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ts-morph/node_modules/typescript": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz", - "integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/ts-node": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", - "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "0.7.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typed-i18next": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/typed-i18next/-/typed-i18next-0.1.2.tgz", - "integrity": "sha512-3Zn04Enaz55WSLKKxj31+pYSvWicYpFAMdIClcErtxLdwU6p1aZ9QU9vhMwYE0qrXSxBTIvViZSy5J54arhJqQ==", - "dev": true, - "dependencies": { - "@types/fs-extra": "^8.0.0", - "chalk": "^2.4.2", - "commander": "^3.0.2", - "fs-extra": "^8.1.0", - "loglevel": "^1.6.4", - "loglevel-plugin-prefix": "^0.8.4", - "ts-morph": "^4.2.0", - "upath": "^1.2.0" - }, - "bin": { - "typed-i18next": "dist/cli/main.js" - } - }, - "node_modules/typed-i18next/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/typed-i18next/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/typed-i18next/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/typed-i18next/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/typed-i18next/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/typed-i18next/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/typed-i18next/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "optional": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/typescript-eslint": { - "version": "0.0.1-alpha.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-0.0.1-alpha.0.tgz", - "integrity": "sha512-1hNKM37dAWML/2ltRXupOq2uqcdRQyDFphl+341NTPXFLLLiDhErXx8VtaSLh3xP7SyHZdcCgpt9boYYVb3fQg==", - "dev": true - }, - "node_modules/unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "optional": true, - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/unit-compare": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unit-compare/-/unit-compare-1.0.1.tgz", - "integrity": "sha1-DHRZ8OW/U2N+qHPKPO4Y3i7so4Y=", - "dependencies": { - "moment": "^2.14.1" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/unzipper": { - "version": "0.10.11", - "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz", - "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", - "dependencies": { - "big-integer": "^1.6.17", - "binary": "~0.3.0", - "bluebird": "~3.4.1", - "buffer-indexof-polyfill": "~1.0.0", - "duplexer2": "~0.1.4", - "fstream": "^1.0.12", - "graceful-fs": "^4.2.2", - "listenercount": "~1.0.1", - "readable-stream": "~2.3.6", - "setimmediate": "~1.0.4" - } - }, - "node_modules/unzipper/node_modules/bluebird": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", - "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=" - }, - "node_modules/unzipper/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/unzipper/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/unzipper/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true, - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/urijs": { - "version": "1.19.7", - "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.7.tgz", - "integrity": "sha512-Id+IKjdU0Hx+7Zx717jwLPsPeUqz7rAtuVBRLLs+qn+J2nf9NGITWVCxcijgYxBqe83C7sqsQPs6H1pyz3x9gA==" - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "optional": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "node_modules/validator": { - "version": "13.7.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", - "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/workerpool": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", - "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "devOptional": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "optional": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/xmldom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz", - "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/xpath": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz", - "integrity": "sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==", - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "devOptional": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "devOptional": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "devOptional": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "node_modules/yazl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", - "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", - "dependencies": { - "buffer-crc32": "~0.2.3" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "devOptional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, + "lockfileVersion": 1, "dependencies": { "@assistant/conversation": { "version": "3.8.1", @@ -5744,8 +113,7 @@ "@firebase/auth-interop-types": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz", - "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==", - "requires": {} + "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==" }, "@firebase/component": { "version": "0.5.7", @@ -6363,8 +731,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "acorn-walk": { "version": "8.2.0", @@ -6400,14 +767,12 @@ "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "devOptional": true + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "devOptional": true, "requires": { "color-convert": "^2.0.1" } @@ -6700,7 +1065,6 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "devOptional": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -6717,7 +1081,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "devOptional": true, "requires": { "color-name": "~1.1.4" } @@ -6725,8 +1088,7 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "devOptional": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "combined-stream": { "version": "1.0.8", @@ -7001,8 +1363,7 @@ "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "devOptional": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "encodeurl": { "version": "1.0.2", @@ -7041,8 +1402,7 @@ "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "devOptional": true + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, "escape-html": { "version": "1.0.3", @@ -7147,8 +1507,7 @@ "version": "0.14.0", "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", - "dev": true, - "requires": {} + "dev": true }, "eslint-scope": { "version": "5.1.1", @@ -7624,8 +1983,7 @@ "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "devOptional": true + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" }, "gaxios": { "version": "4.3.2", @@ -7666,8 +2024,7 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "devOptional": true + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-stream": { "version": "6.0.1", @@ -7924,8 +2281,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "devOptional": true + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, "inflight": { "version": "1.0.6", @@ -7974,8 +2330,7 @@ "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "devOptional": true + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "is-glob": { "version": "4.0.3", @@ -8626,16 +2981,15 @@ } }, "opds-fetcher-parser": { - "version": "git+ssh://git@github.com/edrlab/opds_fetcher_parser.git#eea41a1d50955f39d93670090e480834c26715b4", - "integrity": "sha512-tAgaTwyAL0sqwaCsrO0EzYu5GwOw9A377dYa7ArMk64Ydft2nLktP5/D2PFACzhO3BYEWZCLDzDy5HlSOOnIkw==", - "from": "opds-fetcher-parser@github:edrlab/opds_fetcher_parser#eea41a1d50955f39d93670090e480834c26715b4", + "version": "git+ssh://git@github.com/edrlab/opds_fetcher_parser.git#03a9eb705e05f4ebf02ea2815c47707aec8705c7", + "from": "opds-fetcher-parser@github:edrlab/opds_fetcher_parser#03a9eb705e05f4ebf02ea2815c47707aec8705c7", "requires": { "moment": "^2.29.1", "nanoid": "^3.1.23", "r2-lcp-js": "^1.0.30", "r2-opds-js": "^1.0.35", "r2-shared-js": "^1.0.51", - "ts-fetch": "github:edrlab/ts_fetch#709719be762e4921b6e935f5d7105764cfaccae4" + "ts-fetch": "ts-fetch@github:edrlab/ts_fetch#a55cdd950c57e060f9950808af5ddc5d87754263" } }, "optionator": { @@ -8656,7 +3010,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "devOptional": true, "requires": { "yocto-queue": "^0.1.0" } @@ -9045,8 +3398,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "devOptional": true + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "resolve-from": { "version": "4.0.0", @@ -9271,31 +3623,29 @@ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "optional": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "devOptional": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "optional": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "devOptional": true, "requires": { "ansi-regex": "^5.0.1" } @@ -9382,9 +3732,8 @@ "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=" }, "ts-fetch": { - "version": "git+ssh://git@github.com/edrlab/ts_fetch.git#709719be762e4921b6e935f5d7105764cfaccae4", - "integrity": "sha512-oAbmjoqcPa4E0F0L7RYsGDy0MuYZBWfvt4cG791uZhHNrd0NCgkBGhgbTt8OIQCC4mGiXaqQH6ovGy7g3hxMVg==", - "from": "ts-fetch@github:edrlab/ts_fetch#709719be762e4921b6e935f5d7105764cfaccae4", + "version": "git+ssh://git@github.com/edrlab/ts_fetch.git#a55cdd950c57e060f9950808af5ddc5d87754263", + "from": "ts-fetch@github:edrlab/ts_fetch#a55cdd950c57e060f9950808af5ddc5d87754263", "requires": { "fetch-cookie": "^1.0.0", "node-fetch": "^2.6.7", @@ -9881,7 +4230,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "devOptional": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -9924,8 +4272,7 @@ "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "devOptional": true + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" }, "yallist": { "version": "4.0.0", @@ -9936,7 +4283,6 @@ "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "devOptional": true, "requires": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -9950,8 +4296,7 @@ "yargs-parser": { "version": "20.2.9", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "devOptional": true + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" }, "yargs-unparser": { "version": "2.0.0", @@ -9991,8 +4336,7 @@ "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "devOptional": true + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" } } } diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index 14740d66..fef0ed5b 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -24,7 +24,7 @@ "firebase-admin": "^9.8.0", "firebase-functions": "^3.16.0", "i18next": "^21.5.3", - "opds-fetcher-parser": "github:edrlab/opds_fetcher_parser#eea41a1d50955f39d93670090e480834c26715b4", + "opds-fetcher-parser": "github:edrlab/opds_fetcher_parser#03a9eb705e05f4ebf02ea2815c47707aec8705c7", "reflect-metadata": "^0.1.13" }, "devDependencies": { From 7e3bc327a1f9481fa36ca1c51ed4be694adfdaa8 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 24 Jan 2022 15:21:56 +0100 Subject: [PATCH 075/180] fix: github url for opds_fetcher_parser package --- webhooks/functions/package-lock.json | 179 +++++++++++++++++---------- webhooks/functions/package.json | 2 +- 2 files changed, 114 insertions(+), 67 deletions(-) diff --git a/webhooks/functions/package-lock.json b/webhooks/functions/package-lock.json index 93e9f1ae..77c70813 100644 --- a/webhooks/functions/package-lock.json +++ b/webhooks/functions/package-lock.json @@ -588,11 +588,6 @@ "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.6.6.tgz", "integrity": "sha512-+qogUELb4gMhrMjSh/seKmGVvN+uQLfyqJAqYRWqVHsvBsUO2xDBCL8CJ/ZSukbd8vXaoYbpIssAmfLEzzBHEw==" }, - "@types/xmldom": { - "version": "0.1.31", - "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.31.tgz", - "integrity": "sha512-bVy7s0nvaR5D1mT1a8ZkByHWNOGb6Vn4yi5TWhEdmyKlAG+08SA7Md6+jH+tYmMLueAwNeWvHHpeKrr6S4c4BA==" - }, "@typescript-eslint/eslint-plugin": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.3.1.tgz", @@ -704,6 +699,11 @@ "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, + "@xmldom/xmldom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.0.tgz", + "integrity": "sha512-7wVnF+rKrVDEo1xjzkkidTG0grclaVnX0vKa0z9JSXcEdtftUJjvU33jLGg6SHyvs3eeqEsI7jZ6NxYfRypEEg==" + }, "abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -2261,9 +2261,9 @@ "dev": true }, "image-size": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.0.tgz", - "integrity": "sha512-JLJ6OwBfO1KcA+TvJT+v8gbE6iWbj24LyDNFgFEN0lzegn6cC6a/p3NIDaepMsJjQjlUWqIC7wJv8lBFxPNjcw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.1.tgz", + "integrity": "sha512-VAwkvNSNGClRw9mDHhc5Efax8PLlsOGcUTh0T/LIriC8vPA3U5PdqXWqkz406MoYHMKW8Uf9gWr05T/rYB44kQ==", "requires": { "queue": "6.0.2" } @@ -2458,9 +2458,9 @@ } }, "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" }, "json-schema-traverse": { "version": "0.4.1", @@ -2531,13 +2531,13 @@ } }, "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", - "json-schema": "0.2.3", + "json-schema": "0.4.0", "verror": "1.10.0" } }, @@ -2909,9 +2909,9 @@ } }, "nanoid": { - "version": "3.1.30", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz", - "integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", + "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==" }, "natural-compare": { "version": "1.4.0", @@ -2981,15 +2981,15 @@ } }, "opds-fetcher-parser": { - "version": "git+ssh://git@github.com/edrlab/opds_fetcher_parser.git#03a9eb705e05f4ebf02ea2815c47707aec8705c7", - "from": "opds-fetcher-parser@github:edrlab/opds_fetcher_parser#03a9eb705e05f4ebf02ea2815c47707aec8705c7", + "version": "git+https://github.com/edrlab/opds_fetcher_parser.git#03a9eb705e05f4ebf02ea2815c47707aec8705c7", + "from": "git+https://github.com/edrlab/opds_fetcher_parser.git#03a9eb705e05f4ebf02ea2815c47707aec8705c7", "requires": { "moment": "^2.29.1", "nanoid": "^3.1.23", "r2-lcp-js": "^1.0.30", "r2-opds-js": "^1.0.35", "r2-shared-js": "^1.0.51", - "ts-fetch": "ts-fetch@github:edrlab/ts_fetch#a55cdd950c57e060f9950808af5ddc5d87754263" + "ts-fetch": "github:edrlab/ts_fetch#a55cdd950c57e060f9950808af5ddc5d87754263" } }, "optionator": { @@ -3208,62 +3208,104 @@ "dev": true }, "r2-lcp-js": { - "version": "1.0.33", - "resolved": "https://registry.npmjs.org/r2-lcp-js/-/r2-lcp-js-1.0.33.tgz", - "integrity": "sha512-WNPVjHd1v8appnAqGZ/B8DlRm4k0JdixOc1TSwF+FSrjcBidG+CWijozFEBdPF+DT6FQAZcBc91B+Oc4qw3OJg==", + "version": "1.0.35", + "resolved": "https://registry.npmjs.org/r2-lcp-js/-/r2-lcp-js-1.0.35.tgz", + "integrity": "sha512-e/mrvjhA4W3eRbZsVP3eUn66wncIlK9tTROQARwmtasd2B7Q1csmfpypdWkMTMlJR1u68dduYVNMU4BUkCcKsg==", "requires": { "bindings": "^1.5.0", - "debug": "^4.3.2", + "debug": "^4.3.3", "moment": "^2.29.1", - "r2-utils-js": "^1.0.27", + "r2-utils-js": "^1.0.31", "request": "^2.88.2", "request-promise-native": "^1.0.9", "ta-json-x": "^2.5.3", "tslib": "^2.3.1", "urijs": "^1.19.7" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "requires": { + "ms": "2.1.2" + } + } } }, "r2-opds-js": { - "version": "1.0.38", - "resolved": "https://registry.npmjs.org/r2-opds-js/-/r2-opds-js-1.0.38.tgz", - "integrity": "sha512-yZB1BFmfrxgvIIe1t+p7nWrMcSS+8ge9NJIDaPe1Zq6rHpC8IlBy5HvdCgGN6pX7Ix1u3VbI1zy/KxVFUPzAsg==", - "requires": { - "debug": "^4.3.2", - "r2-lcp-js": "^1.0.33", - "r2-shared-js": "^1.0.53", - "r2-utils-js": "^1.0.27", + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/r2-opds-js/-/r2-opds-js-1.0.39.tgz", + "integrity": "sha512-x7Ds5sY0w/N65DQ/OQAUy8wpBXTODklVEurHlt7peO0MeGki4PMYsnM9FUitrWxqJj0NQtNDOkS24GF8GbFPdA==", + "requires": { + "@xmldom/xmldom": "^0.8.0", + "debug": "^4.3.3", + "r2-lcp-js": "^1.0.34", + "r2-shared-js": "^1.0.55", + "r2-utils-js": "^1.0.30", "ta-json-x": "^2.5.3", - "tslib": "^2.3.1", - "xmldom": "^0.6.0" + "tslib": "^2.3.1" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "requires": { + "ms": "2.1.2" + } + } } }, "r2-shared-js": { - "version": "1.0.53", - "resolved": "https://registry.npmjs.org/r2-shared-js/-/r2-shared-js-1.0.53.tgz", - "integrity": "sha512-1LyAd5Ebhyfe2gRFg8wE0wS9yK+bYDBfRZLpCxCX5O3JNdSwuVwLAff6qLhk7ExagifFRB4ZUNMpW1n3zEUi+Q==", + "version": "1.0.55", + "resolved": "https://registry.npmjs.org/r2-shared-js/-/r2-shared-js-1.0.55.tgz", + "integrity": "sha512-kON3ZOXThEkbxJS0yZ8OD604kzEDq87rB8akdB6l5QR9LCs38nvRDxkEtnt0ZVVYmQnd80GXg2yH5c/OR4YBEw==", "requires": { - "debug": "^4.3.2", + "@xmldom/xmldom": "^0.8.0", + "debug": "^4.3.3", "fast-deep-equal": "^3.1.3", "image-size": "^1.0.0", - "mime-types": "^2.1.33", + "mime-types": "^2.1.34", "moment": "^2.29.1", - "r2-lcp-js": "^1.0.33", - "r2-utils-js": "^1.0.27", - "slugify": "^1.6.1", + "r2-lcp-js": "^1.0.34", + "r2-utils-js": "^1.0.30", + "slugify": "^1.6.5", "ta-json-x": "^2.5.3", "tslib": "^2.3.1", - "xmldom": "^0.6.0", "xpath": "^0.0.32", "yazl": "^2.5.1" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "requires": { + "ms": "2.1.2" + } + }, + "mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" + }, + "mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "requires": { + "mime-db": "1.51.0" + } + } } }, "r2-utils-js": { - "version": "1.0.27", - "resolved": "https://registry.npmjs.org/r2-utils-js/-/r2-utils-js-1.0.27.tgz", - "integrity": "sha512-uZ0P/JBKY16JAsL5FwH/r2k+9Jq30i7IdWxsa26mki/2DHALE4lv+Qs80kU68pHWKXS+eeriyCkCTCmI32TJTw==", + "version": "1.0.31", + "resolved": "https://registry.npmjs.org/r2-utils-js/-/r2-utils-js-1.0.31.tgz", + "integrity": "sha512-MUtInLoqkwxNFJa9s7vjY2uDpxz1+ei3/x6KVefbuOEDE7KYKtuSUIwPhXgn6uSizZeN/A+2hZK/zi7s5q9fpA==", "requires": { - "@types/xmldom": "^0.1.31", - "debug": "^4.3.2", + "debug": "^4.3.3", "filehound": "^1.17.5", "node-stream-zip": "^1.15.0", "reflect-metadata": "^0.1.13", @@ -3275,6 +3317,16 @@ "xpath": "^0.0.32", "yauzl": "^2.10.0", "yazl": "^2.5.1" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "requires": { + "ms": "2.1.2" + } + } } }, "randombytes": { @@ -3366,9 +3418,9 @@ }, "dependencies": { "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==" }, "uuid": { "version": "3.4.0", @@ -3567,9 +3619,9 @@ "dev": true }, "slugify": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.2.tgz", - "integrity": "sha512-XMtI8qD84LwCpthLMBHlIhcrj10cgA+U/Ot8G6FD6uFuWZtMfKK75JO7l81nzpFJsPlsW6LT+VKqWQJW3+6New==" + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.5.tgz", + "integrity": "sha512-8mo9bslnBO3tr5PEVFzMPIWwWnipGS0xVbYf65zxDqfNwmzYn1LpiKNrR6DlClusuvo+hDHd1zKpmfAe83NQSQ==" }, "snakeize": { "version": "0.1.0", @@ -3578,9 +3630,9 @@ "optional": true }, "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -3732,8 +3784,8 @@ "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=" }, "ts-fetch": { - "version": "git+ssh://git@github.com/edrlab/ts_fetch.git#a55cdd950c57e060f9950808af5ddc5d87754263", - "from": "ts-fetch@github:edrlab/ts_fetch#a55cdd950c57e060f9950808af5ddc5d87754263", + "version": "github:edrlab/ts_fetch#a55cdd950c57e060f9950808af5ddc5d87754263", + "from": "github:edrlab/ts_fetch#a55cdd950c57e060f9950808af5ddc5d87754263", "requires": { "fetch-cookie": "^1.0.0", "node-fetch": "^2.6.7", @@ -4259,11 +4311,6 @@ "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "optional": true }, - "xmldom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz", - "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==" - }, "xpath": { "version": "0.0.32", "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz", diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index fef0ed5b..3bf461f1 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -24,7 +24,7 @@ "firebase-admin": "^9.8.0", "firebase-functions": "^3.16.0", "i18next": "^21.5.3", - "opds-fetcher-parser": "github:edrlab/opds_fetcher_parser#03a9eb705e05f4ebf02ea2815c47707aec8705c7", + "opds-fetcher-parser": "git+https://github.com/edrlab/opds_fetcher_parser.git#03a9eb705e05f4ebf02ea2815c47707aec8705c7", "reflect-metadata": "^0.1.13" }, "devDependencies": { From 2eb9bb3bba2188271472f7a0c1f667d6c493e28b Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 24 Jan 2022 15:36:32 +0100 Subject: [PATCH 076/180] fix: missing import URL with node14 --- webhooks/functions/src/index.ts | 1 + webhooks/functions/src/utils/index.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index f2381571..631eca69 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -2,6 +2,7 @@ import {conversation, Media } from "@assistant/conversation"; import * as functions from "firebase-functions"; import {http as Http, AuthenticationStorage, OpdsFetcher} from "opds-fetcher-parser"; import {ok as _ok} from "assert"; +import {URL} from "url"; // class-transformer import 'reflect-metadata'; diff --git a/webhooks/functions/src/utils/index.ts b/webhooks/functions/src/utils/index.ts index 79b56e6f..b6f0cf92 100644 --- a/webhooks/functions/src/utils/index.ts +++ b/webhooks/functions/src/utils/index.ts @@ -1,6 +1,7 @@ import {OpdsFetcher} from 'opds-fetcher-parser'; import * as assert from 'assert'; import {IOpdsLinkView} from 'opds-fetcher-parser/build/src/interface/opds'; +import {URL} from 'url'; export function isValidHttpUrl(url: string | undefined): url is string { let _url: URL; From eb70d1e67b119fdf4998f282c37192c5723b1fb2 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 31 Jan 2022 11:52:57 +0100 Subject: [PATCH 077/180] first --- flowchart.drawio | 1 + 1 file changed, 1 insertion(+) create mode 100644 flowchart.drawio diff --git a/flowchart.drawio b/flowchart.drawio new file mode 100644 index 00000000..5534237d --- /dev/null +++ b/flowchart.drawio @@ -0,0 +1 @@ +ddG9DoMgEADgp2FXSNTO1raLk0NnIlchQc8gjbZPXw2oJbYLOb6745ewvJ2uhveyRAGa0EhMhJ0JpWmWzOMCLwdxnKROGqOEtx0q9QaPkdenEjAEhRZRW9WHWGPXQW0D48bgGJY9UIe79ryBA1Q110e9K2Gl04ymu99ANdJu9zu5TMvXYn+TQXKB4xexgrDcIFoXtVMOenm89V1c3+VPdjuYgc7+aJiDfe15EvwQKz4= \ No newline at end of file From 7208c73cdd3da50670bc4bc9356a3b7385e8c053 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 31 Jan 2022 13:12:50 +0100 Subject: [PATCH 078/180] flow --- flowchart.drawio | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flowchart.drawio b/flowchart.drawio index 5534237d..2c9fe9ff 100644 --- a/flowchart.drawio +++ b/flowchart.drawio @@ -1 +1 @@ -ddG9DoMgEADgp2FXSNTO1raLk0NnIlchQc8gjbZPXw2oJbYLOb6745ewvJ2uhveyRAGa0EhMhJ0JpWmWzOMCLwdxnKROGqOEtx0q9QaPkdenEjAEhRZRW9WHWGPXQW0D48bgGJY9UIe79ryBA1Q110e9K2Gl04ymu99ANdJu9zu5TMvXYn+TQXKB4xexgrDcIFoXtVMOenm89V1c3+VPdjuYgc7+aJiDfe15EvwQKz4= \ No newline at end of file +7VlLc9s2EP4tPWimPUgjknrlaMt2mtZN3XE7iU8ZiARJ2BDAAqAe+fXdBcGXSLl2Gj/SyYUkdrEAuPh2vwU5CJbr3VtFsvQ3GVE+8MfRbhCcDXzfezMdww0leyeZzeaFJFEscrJacM0+Uyd0hknOIqpbHY2U3LCsLQylEDQ0LRlRSm7b3WLJ27NmJKEdwXVIeFf6gUUmLaQLf17Lf6YsScuZvdmbQrMmZWf3Jjolkdw2RMH5IFgqKU3xtN4tKUfvlX4p7C6OaKuFKSrMQwzixe/6U3zzcXzyx+17IfNf1NXt0I2yITx3LzzwZxzGO9UZEfCc4HMpg8H7xF/Y9QPloVxTu6MDXPx4L3MFt+X55QncLtlKEbX/weoK85U6HLCW/ImDxDnne7hTcSv39Ygkj5hcSXmnsSEivIYh1bruklGlpSDoMU05QIlJWOmy6ADXLbPeFJRG5Yo5E3edVcO4Mhdm1F3gB5nzqBqPs7vq1SO8aLwIRMjFUSdaHJl9CU4FM0UU99cD9TZlhl5nJETtFuIRZKlZc6dOSZjmir5F+dkEBJlkwlB1vgEAYZSMqyk2VBm6O4ozr0IvxD2FLTQKfe0MJg7vLuKDmWtv6/AJyuhOm6ETOCFxIZtUQ9eohgcH7EeAfNpxHI0gyF1TSAG30zBXm8qVtWPRKVKZVCYIjkspM9fllhqzd/mK5LCNLWfTHTMf0Xw0da2bhuZs50a2jX3ZEPCyDSNs3jR1tZlt1XbRCWY6aMqMCowyQ5Rxa/MmRZdmUwNiQ3pFFQMHU4WYYSIB7QKUYJtQc0RZeBLddz86EM44xz274rtsbqe7p9+kH22KcmLYpr2Orw4dv5Mfr9G3HUBBcs/wERxBOKdcJoqsMcZKNx7qrmrFvwVuzHa02r5nDORg3o7kRTeQPb8nkGdPFcfBqyCrFQnvysT9CMJaSgH7bnJErRQaO91YIkjJBofVORJSyV9ILTRqEFjBKhV7hbgyyxYNJiPWhTKuzWKykQrAhctG9vvhMaykKVFhaosmuwQUZTRkMQvdeDhbQa+QIFXBlkhnTIcSoIdquwwDWdMfB4g+FloOtmbb1tSZorG1sdkLU04xp5soVnJdv5h9m5Ty+Ftny+n0gC6nL06XixekywZZ1tT5nS5LGnwAXR6B24Pp0pqCg8i+0cGCXzdGvkJBjWI46LVQXHJADcNixBqU1dK+HKfepMMHf72/fPf+1/OzXgRfkhWcTlu4I5wlgICzkIqCijGWGZz+TpxizaIIxzhVVLPPZGXHG5fpwHpnejqYnt2XDNzR1BnXB8ImCo4H4tHMMR5NFnO/7XbHkI/b7Ho3yy4yjjU1nUTyNfZs3Ls1z5JcvO/J5b8ml+Alksts0aZIfz59huTSLTb/T6nFG/fvZJVbxovFvOX1oTd/7cmlywfvoBaekTXWdmKls0ZtnwatXZz9neN3uNM1RACD3cFyfpzt4Dr0i7u1BcdGkY3AuoPTe81uK6kiqoYraQxUrbazTW2lPpQcKmArV8nqx2BiC2csn1uPP1UGsRRmGJM1g9OBNavea+AHgc0jNJE4Qc46qmpETYQeasgmcf3GZblcnTAK/2zrE8IlnEVsOd7RwFnY5LpRf6NXj1XfqVyvoPOrqbyDg8ob9rN7vp31Vd7Tp6q8veOfY/EklMIJqYXW1Bj8DH6Cs/oXxH6z1EMphomUCaejhJk0X42YRK3WDLgIYARJAxyn7Tl0KGREb2ELL4LRfATvdRFy6ElR0uz3KYVzJ6fqUw7wGdmL3TI/cLjhBUh0iYgDdL3ilZbYJUehCxgzbYxqo+QdXRZRXFYtMeP8QPRwEugLinbl82zfbw/o1vO6cTHpjYv5k8XFtCcuXnt+8abtM9F03vXjoseNiyfz4qzjxT3V3XqGc5bpY5h8AUcOq5+BzpOznl8KfZ58OjzOO54U8htw5Jtn8yM06z+bRX1X/yAOzv8B \ No newline at end of file From e77f83cffaefe6d0ae435f7b0adc8659fec7301c Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 31 Jan 2022 13:51:47 +0100 Subject: [PATCH 079/180] [skip ci] deploy actions --- .../workflows/{functions-dev.yml => functions-avh-dev.yml} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename .github/workflows/{functions-dev.yml => functions-avh-dev.yml} (96%) diff --git a/.github/workflows/functions-dev.yml b/.github/workflows/functions-avh-dev.yml similarity index 96% rename from .github/workflows/functions-dev.yml rename to .github/workflows/functions-avh-dev.yml index f0607a50..2ed7ab84 100644 --- a/.github/workflows/functions-dev.yml +++ b/.github/workflows/functions-avh-dev.yml @@ -3,10 +3,10 @@ name: functions deploy on: push: - branches: [ develop ] + branches: [ avh-dev ] paths: - 'webhooks/**' - - '.github/workflows/functions-dev.yml' + - '.github/workflows/functions-avh-dev.yml' jobs: deploy: @@ -94,4 +94,4 @@ jobs: env: SECRET : ${{ secrets.SERVICE_ACCOUNT_VALENTIN5 }} - run: npm install - - run: npm test \ No newline at end of file + - run: npm test From 5f0cb523b41bc49514b76ce00cdb6f38025f414a Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 31 Jan 2022 14:32:56 +0100 Subject: [PATCH 080/180] chore: new develop branch with edrlab-1 --- ...tions-dev.yml => functions-edrlab-dev.yml} | 6 +- .github/workflows/functions.yml | 58 ------------------- README.md | 8 ++- 3 files changed, 9 insertions(+), 63 deletions(-) rename .github/workflows/{functions-dev.yml => functions-edrlab-dev.yml} (96%) delete mode 100644 .github/workflows/functions.yml diff --git a/.github/workflows/functions-dev.yml b/.github/workflows/functions-edrlab-dev.yml similarity index 96% rename from .github/workflows/functions-dev.yml rename to .github/workflows/functions-edrlab-dev.yml index f0607a50..d88207e5 100644 --- a/.github/workflows/functions-dev.yml +++ b/.github/workflows/functions-edrlab-dev.yml @@ -6,7 +6,7 @@ on: branches: [ develop ] paths: - 'webhooks/**' - - '.github/workflows/functions-dev.yml' + - '.github/workflows/functions-edrlab-dev.yml' jobs: deploy: @@ -19,7 +19,7 @@ jobs: env: working-directory: './webhooks/functions' - project-id: 'valentin-5' + project-id: 'edrlab-1' defaults: run: working-directory: './webhooks/functions' @@ -94,4 +94,4 @@ jobs: env: SECRET : ${{ secrets.SERVICE_ACCOUNT_VALENTIN5 }} - run: npm install - - run: npm test \ No newline at end of file + - run: npm test diff --git a/.github/workflows/functions.yml b/.github/workflows/functions.yml deleted file mode 100644 index e2ac0bf4..00000000 --- a/.github/workflows/functions.yml +++ /dev/null @@ -1,58 +0,0 @@ - -name: functions deploy - -on: - push: - branches: [ main ] - paths: - - 'functions/**' - - '.github/workflows/functions.yml' - -jobs: - deploy: - name: "Deploy Firebase functions" - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [16.x] - # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ - - env: - working-directory: './functions/functions' - defaults: - run: - working-directory: './functions/functions' - - steps: - - name: Checkout repo - uses: actions/checkout@v2 - - - name : GITHUB CONTEXT - env: - GITHUB_CONTEXT: ${{ toJson(github) }} - run: echo "$GITHUB_CONTEXT" - - - name: Install node ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - - name: Install Dependencies - run: npm ci --no-audit - working-directory: ${{ env.working-directory }} - - - name: set commit name to function config - uses: w9jds/firebase-action@master - with: - args: functions:config:set debug.message=\"${{ github.event.head_commit.message }}\" - env: - FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} - PROJECT_PATH: './functions' - - - name: Deploy to Firebase - uses: w9jds/firebase-action@master - with: - args: deploy --only \"functions:ActionsOnGoogleFulfillment\" --message \"${{ github.event.head_commit.message }}\" - env: - FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} - PROJECT_PATH: './functions' diff --git a/README.md b/README.md index fdf849b3..6d81e05b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,11 @@ # lis-mon-livre +> develop branch + - https://console.firebase.google.com/u/1/project/edrlab-1/firestore/data + - https://console.actions.google.com/u/1/project/edrlab-1/overview + - https://console.cloud.google.com/logs/query?referrer=search&authuser=1&project=edrlab-1 -## gactions +## gactions sdk -`cd sdk && gactions pull --force --clean --project-id valentin-4` +`cd sdk && gactions pull --force --clean --project-id edrlab-1` From 47348e14cbf06c61c4a38b400777074f86de34da Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 31 Jan 2022 15:40:28 +0100 Subject: [PATCH 081/180] chore develop --- .github/workflows/webhooks-test.yml | 4 +- sdk/{test => }/actions/actions.yaml | 0 .../custom/global/actions.intent.CANCEL.yaml | 0 .../custom/global/actions.intent.MAIN.yaml | 0 .../actions.intent.MEDIA_STATUS_STOPPED.yaml | 0 .../global/actions.intent.NO_INPUT_1.yaml | 0 .../global/actions.intent.NO_INPUT_2.yaml | 0 .../global/actions.intent.NO_INPUT_FINAL.yaml | 0 .../global/actions.intent.NO_MATCH_1.yaml | 0 .../global/actions.intent.NO_MATCH_2.yaml | 0 .../global/actions.intent.NO_MATCH_FINAL.yaml | 0 .../intents/enter_member_space_lvl1.yaml | 0 .../intents/get_info_association_lvl1.yaml | 0 .../custom/intents/i_want_to_listen_lvl3.yaml | 0 .../custom/intents/listen_audiobook_lvl1.yaml | 0 .../custom/intents/listen_audiobook_lvl2.yaml | 0 sdk/{test => }/custom/intents/listen_toc.yaml | 0 sdk/{test => }/custom/intents/menu.yaml | 0 sdk/{test => }/custom/intents/next.yaml | 0 sdk/{prod => }/custom/intents/no.yaml | 0 .../custom/intents/remaing_time_player.yaml | 0 sdk/{test => }/custom/intents/repeat.yaml | 0 .../custom/intents/resume_audiobook_lvl2.yaml | 0 .../intents/resume_listening_player.yaml | 0 .../selection_all_publication_lvl3.yaml | 0 .../intents/selection_audiobook_lvl2.yaml | 0 .../custom/intents/selection_genre_lvl3.yaml | 0 .../intents/selection_my_list_lvl3.yaml | 0 .../intents/selection_thematic_list_lvl3.yaml | 0 sdk/{test => }/custom/intents/stop.yaml | 0 .../custom/intents/test_player_sdk.yaml | 0 .../custom/intents/test_setup_sdk.yaml | 0 .../custom/intents/test_webhook.yaml | 0 sdk/{prod => }/custom/intents/yes.yaml | 0 ...sk_to_resume_listening_at_last_offset.yaml | 0 sdk/{test => }/custom/scenes/home_lvl1.yaml | 0 .../scenes/home_lvl1_AccountLinking.yaml | 0 .../custom/scenes/home_members_lvl2.yaml | 0 sdk/{test => }/custom/scenes/player.yaml | 0 sdk/{test => }/custom/scenes/player_toc.yaml | 0 sdk/{test => }/custom/scenes/search.yaml | 0 .../custom/scenes/select_group.yaml | 0 .../custom/scenes/select_publication.yaml | 0 .../custom/scenes/selection_lvl3.yaml | 0 sdk/{prod => }/custom/types/string.yaml | 0 sdk/{prod => }/manifest.yaml | 0 sdk/prod/actions/actions.yaml | 2 - .../custom/global/actions.intent.MAIN.yaml | 9 - .../custom/intents/resume_audiobook_lvl2.yaml | 15 - .../intents/resume_listening_player.yaml | 3 - ...sk_to_resume_listening_at_last_offset.yaml | 11 - sdk/prod/custom/scenes/home_lvl1.yaml | 31 - sdk/prod/custom/scenes/home_members_lvl2.yaml | 25 - sdk/prod/custom/scenes/player.yaml | 21 - sdk/prod/custom/scenes/search.yaml | 21 - .../scenes/select_pub_after_search.yaml | 69 - .../scenes/select_pub_after_selection.yaml | 67 - sdk/prod/custom/scenes/selection_lvl3.yaml | 10 - sdk/prod/settings/settings.yaml | 24 - .../webhooks/ActionsOnGoogleFulfillment.yaml | 22 - sdk/{test => }/settings/settings.yaml | 12 +- .../custom/global/actions.intent.CANCEL.yaml | 9 - .../global/actions.intent.NO_INPUT_1.yaml | 7 - .../global/actions.intent.NO_INPUT_2.yaml | 7 - .../global/actions.intent.NO_INPUT_FINAL.yaml | 8 - .../global/actions.intent.NO_MATCH_1.yaml | 7 - .../global/actions.intent.NO_MATCH_2.yaml | 7 - .../global/actions.intent.NO_MATCH_FINAL.yaml | 8 - .../intents/enter_member_space_lvl1.yaml | 5 - .../intents/get_info_association_lvl1.yaml | 4 - .../custom/intents/i_want_to_listen_lvl3.yaml | 10 - .../custom/intents/listen_audiobook_lvl1.yaml | 6 - .../custom/intents/listen_audiobook_lvl2.yaml | 12 - sdk/test/custom/intents/no.yaml | 5 - .../custom/intents/remaing_time_player.yaml | 7 - .../intents/selection_audiobook_lvl2.yaml | 5 - .../custom/intents/selection_genre_lvl3.yaml | 4 - .../intents/selection_my_list_lvl3.yaml | 4 - .../intents/selection_thematic_list_lvl3.yaml | 4 - sdk/test/custom/intents/test_webhook.yaml | 3 - sdk/test/custom/intents/yes.yaml | 6 - .../scenes/home_lvl1_AccountLinking.yaml | 19 - sdk/test/custom/types/string.yaml | 1 - sdk/test/manifest.yaml | 1 - .../webhooks/ActionsOnGoogleFulfillment.yaml | 2 +- test/{dev => }/.eslintrc.json | 0 test/{dev => }/package-lock.json | 0 test/{dev => }/package.json | 0 test/prod/.eslintrc.json | 20 - test/prod/package-lock.json | 3161 ----------------- test/prod/package.json | 25 - test/prod/test/test1.ts | 56 - test/{dev => }/test/constant.ts | 0 test/{dev => }/test/test1.ts | 0 test/{dev => }/test/test10.ts | 0 test/{dev => }/test/test11.ts | 0 test/{dev => }/test/test12.ts | 0 test/{dev => }/test/test13.ts | 0 test/{dev => }/test/test2.ts | 0 test/{dev => }/test/test3-2.ts | 0 test/{dev => }/test/test3.ts | 0 test/{dev => }/test/test4.ts | 0 test/{dev => }/test/test5.ts | 0 test/{dev => }/test/test6.ts | 0 test/{dev => }/test/test7.ts | 0 test/{dev => }/test/test8.ts | 0 test/{dev => }/test/test9.ts | 0 107 files changed, 9 insertions(+), 3750 deletions(-) rename sdk/{test => }/actions/actions.yaml (100%) rename sdk/{prod => }/custom/global/actions.intent.CANCEL.yaml (100%) rename sdk/{test => }/custom/global/actions.intent.MAIN.yaml (100%) rename sdk/{test => }/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml (100%) rename sdk/{prod => }/custom/global/actions.intent.NO_INPUT_1.yaml (100%) rename sdk/{prod => }/custom/global/actions.intent.NO_INPUT_2.yaml (100%) rename sdk/{prod => }/custom/global/actions.intent.NO_INPUT_FINAL.yaml (100%) rename sdk/{prod => }/custom/global/actions.intent.NO_MATCH_1.yaml (100%) rename sdk/{prod => }/custom/global/actions.intent.NO_MATCH_2.yaml (100%) rename sdk/{prod => }/custom/global/actions.intent.NO_MATCH_FINAL.yaml (100%) rename sdk/{prod => }/custom/intents/enter_member_space_lvl1.yaml (100%) rename sdk/{prod => }/custom/intents/get_info_association_lvl1.yaml (100%) rename sdk/{prod => }/custom/intents/i_want_to_listen_lvl3.yaml (100%) rename sdk/{prod => }/custom/intents/listen_audiobook_lvl1.yaml (100%) rename sdk/{prod => }/custom/intents/listen_audiobook_lvl2.yaml (100%) rename sdk/{test => }/custom/intents/listen_toc.yaml (100%) rename sdk/{test => }/custom/intents/menu.yaml (100%) rename sdk/{test => }/custom/intents/next.yaml (100%) rename sdk/{prod => }/custom/intents/no.yaml (100%) rename sdk/{prod => }/custom/intents/remaing_time_player.yaml (100%) rename sdk/{test => }/custom/intents/repeat.yaml (100%) rename sdk/{test => }/custom/intents/resume_audiobook_lvl2.yaml (100%) rename sdk/{test => }/custom/intents/resume_listening_player.yaml (100%) rename sdk/{test => }/custom/intents/selection_all_publication_lvl3.yaml (100%) rename sdk/{prod => }/custom/intents/selection_audiobook_lvl2.yaml (100%) rename sdk/{prod => }/custom/intents/selection_genre_lvl3.yaml (100%) rename sdk/{prod => }/custom/intents/selection_my_list_lvl3.yaml (100%) rename sdk/{prod => }/custom/intents/selection_thematic_list_lvl3.yaml (100%) rename sdk/{test => }/custom/intents/stop.yaml (100%) rename sdk/{test => }/custom/intents/test_player_sdk.yaml (100%) rename sdk/{test => }/custom/intents/test_setup_sdk.yaml (100%) rename sdk/{prod => }/custom/intents/test_webhook.yaml (100%) rename sdk/{prod => }/custom/intents/yes.yaml (100%) rename sdk/{test => }/custom/scenes/ask_to_resume_listening_at_last_offset.yaml (100%) rename sdk/{test => }/custom/scenes/home_lvl1.yaml (100%) rename sdk/{prod => }/custom/scenes/home_lvl1_AccountLinking.yaml (100%) rename sdk/{test => }/custom/scenes/home_members_lvl2.yaml (100%) rename sdk/{test => }/custom/scenes/player.yaml (100%) rename sdk/{test => }/custom/scenes/player_toc.yaml (100%) rename sdk/{test => }/custom/scenes/search.yaml (100%) rename sdk/{test => }/custom/scenes/select_group.yaml (100%) rename sdk/{test => }/custom/scenes/select_publication.yaml (100%) rename sdk/{test => }/custom/scenes/selection_lvl3.yaml (100%) rename sdk/{prod => }/custom/types/string.yaml (100%) rename sdk/{prod => }/manifest.yaml (100%) delete mode 100644 sdk/prod/actions/actions.yaml delete mode 100644 sdk/prod/custom/global/actions.intent.MAIN.yaml delete mode 100644 sdk/prod/custom/intents/resume_audiobook_lvl2.yaml delete mode 100644 sdk/prod/custom/intents/resume_listening_player.yaml delete mode 100644 sdk/prod/custom/scenes/ask_to_resume_listening_at_last_offset.yaml delete mode 100644 sdk/prod/custom/scenes/home_lvl1.yaml delete mode 100644 sdk/prod/custom/scenes/home_members_lvl2.yaml delete mode 100644 sdk/prod/custom/scenes/player.yaml delete mode 100644 sdk/prod/custom/scenes/search.yaml delete mode 100644 sdk/prod/custom/scenes/select_pub_after_search.yaml delete mode 100644 sdk/prod/custom/scenes/select_pub_after_selection.yaml delete mode 100644 sdk/prod/custom/scenes/selection_lvl3.yaml delete mode 100644 sdk/prod/settings/settings.yaml delete mode 100644 sdk/prod/webhooks/ActionsOnGoogleFulfillment.yaml rename sdk/{test => }/settings/settings.yaml (68%) delete mode 100644 sdk/test/custom/global/actions.intent.CANCEL.yaml delete mode 100644 sdk/test/custom/global/actions.intent.NO_INPUT_1.yaml delete mode 100644 sdk/test/custom/global/actions.intent.NO_INPUT_2.yaml delete mode 100644 sdk/test/custom/global/actions.intent.NO_INPUT_FINAL.yaml delete mode 100644 sdk/test/custom/global/actions.intent.NO_MATCH_1.yaml delete mode 100644 sdk/test/custom/global/actions.intent.NO_MATCH_2.yaml delete mode 100644 sdk/test/custom/global/actions.intent.NO_MATCH_FINAL.yaml delete mode 100644 sdk/test/custom/intents/enter_member_space_lvl1.yaml delete mode 100644 sdk/test/custom/intents/get_info_association_lvl1.yaml delete mode 100644 sdk/test/custom/intents/i_want_to_listen_lvl3.yaml delete mode 100644 sdk/test/custom/intents/listen_audiobook_lvl1.yaml delete mode 100644 sdk/test/custom/intents/listen_audiobook_lvl2.yaml delete mode 100644 sdk/test/custom/intents/no.yaml delete mode 100644 sdk/test/custom/intents/remaing_time_player.yaml delete mode 100644 sdk/test/custom/intents/selection_audiobook_lvl2.yaml delete mode 100644 sdk/test/custom/intents/selection_genre_lvl3.yaml delete mode 100644 sdk/test/custom/intents/selection_my_list_lvl3.yaml delete mode 100644 sdk/test/custom/intents/selection_thematic_list_lvl3.yaml delete mode 100644 sdk/test/custom/intents/test_webhook.yaml delete mode 100644 sdk/test/custom/intents/yes.yaml delete mode 100644 sdk/test/custom/scenes/home_lvl1_AccountLinking.yaml delete mode 100644 sdk/test/custom/types/string.yaml delete mode 100644 sdk/test/manifest.yaml rename sdk/{test => }/webhooks/ActionsOnGoogleFulfillment.yaml (95%) rename test/{dev => }/.eslintrc.json (100%) rename test/{dev => }/package-lock.json (100%) rename test/{dev => }/package.json (100%) delete mode 100644 test/prod/.eslintrc.json delete mode 100644 test/prod/package-lock.json delete mode 100644 test/prod/package.json delete mode 100644 test/prod/test/test1.ts rename test/{dev => }/test/constant.ts (100%) rename test/{dev => }/test/test1.ts (100%) rename test/{dev => }/test/test10.ts (100%) rename test/{dev => }/test/test11.ts (100%) rename test/{dev => }/test/test12.ts (100%) rename test/{dev => }/test/test13.ts (100%) rename test/{dev => }/test/test2.ts (100%) rename test/{dev => }/test/test3-2.ts (100%) rename test/{dev => }/test/test3.ts (100%) rename test/{dev => }/test/test4.ts (100%) rename test/{dev => }/test/test5.ts (100%) rename test/{dev => }/test/test6.ts (100%) rename test/{dev => }/test/test7.ts (100%) rename test/{dev => }/test/test8.ts (100%) rename test/{dev => }/test/test9.ts (100%) diff --git a/.github/workflows/webhooks-test.yml b/.github/workflows/webhooks-test.yml index 2f1dff2e..3a9fd450 100644 --- a/.github/workflows/webhooks-test.yml +++ b/.github/workflows/webhooks-test.yml @@ -3,10 +3,10 @@ name: webhooks unitary tests on: push: - branches: [ develop, mainp ] + branches: [ develop, avh-prod, avh-dev, cela-prod, cela-dev ] # paths: pull_request: - branches: [ develop, main ] + branches: [ develop, avh-prod, avh-dev, cela-prod, cela-dev ] jobs: sdk-test-prod: diff --git a/sdk/test/actions/actions.yaml b/sdk/actions/actions.yaml similarity index 100% rename from sdk/test/actions/actions.yaml rename to sdk/actions/actions.yaml diff --git a/sdk/prod/custom/global/actions.intent.CANCEL.yaml b/sdk/custom/global/actions.intent.CANCEL.yaml similarity index 100% rename from sdk/prod/custom/global/actions.intent.CANCEL.yaml rename to sdk/custom/global/actions.intent.CANCEL.yaml diff --git a/sdk/test/custom/global/actions.intent.MAIN.yaml b/sdk/custom/global/actions.intent.MAIN.yaml similarity index 100% rename from sdk/test/custom/global/actions.intent.MAIN.yaml rename to sdk/custom/global/actions.intent.MAIN.yaml diff --git a/sdk/test/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml b/sdk/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml similarity index 100% rename from sdk/test/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml rename to sdk/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml diff --git a/sdk/prod/custom/global/actions.intent.NO_INPUT_1.yaml b/sdk/custom/global/actions.intent.NO_INPUT_1.yaml similarity index 100% rename from sdk/prod/custom/global/actions.intent.NO_INPUT_1.yaml rename to sdk/custom/global/actions.intent.NO_INPUT_1.yaml diff --git a/sdk/prod/custom/global/actions.intent.NO_INPUT_2.yaml b/sdk/custom/global/actions.intent.NO_INPUT_2.yaml similarity index 100% rename from sdk/prod/custom/global/actions.intent.NO_INPUT_2.yaml rename to sdk/custom/global/actions.intent.NO_INPUT_2.yaml diff --git a/sdk/prod/custom/global/actions.intent.NO_INPUT_FINAL.yaml b/sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml similarity index 100% rename from sdk/prod/custom/global/actions.intent.NO_INPUT_FINAL.yaml rename to sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml diff --git a/sdk/prod/custom/global/actions.intent.NO_MATCH_1.yaml b/sdk/custom/global/actions.intent.NO_MATCH_1.yaml similarity index 100% rename from sdk/prod/custom/global/actions.intent.NO_MATCH_1.yaml rename to sdk/custom/global/actions.intent.NO_MATCH_1.yaml diff --git a/sdk/prod/custom/global/actions.intent.NO_MATCH_2.yaml b/sdk/custom/global/actions.intent.NO_MATCH_2.yaml similarity index 100% rename from sdk/prod/custom/global/actions.intent.NO_MATCH_2.yaml rename to sdk/custom/global/actions.intent.NO_MATCH_2.yaml diff --git a/sdk/prod/custom/global/actions.intent.NO_MATCH_FINAL.yaml b/sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml similarity index 100% rename from sdk/prod/custom/global/actions.intent.NO_MATCH_FINAL.yaml rename to sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml diff --git a/sdk/prod/custom/intents/enter_member_space_lvl1.yaml b/sdk/custom/intents/enter_member_space_lvl1.yaml similarity index 100% rename from sdk/prod/custom/intents/enter_member_space_lvl1.yaml rename to sdk/custom/intents/enter_member_space_lvl1.yaml diff --git a/sdk/prod/custom/intents/get_info_association_lvl1.yaml b/sdk/custom/intents/get_info_association_lvl1.yaml similarity index 100% rename from sdk/prod/custom/intents/get_info_association_lvl1.yaml rename to sdk/custom/intents/get_info_association_lvl1.yaml diff --git a/sdk/prod/custom/intents/i_want_to_listen_lvl3.yaml b/sdk/custom/intents/i_want_to_listen_lvl3.yaml similarity index 100% rename from sdk/prod/custom/intents/i_want_to_listen_lvl3.yaml rename to sdk/custom/intents/i_want_to_listen_lvl3.yaml diff --git a/sdk/prod/custom/intents/listen_audiobook_lvl1.yaml b/sdk/custom/intents/listen_audiobook_lvl1.yaml similarity index 100% rename from sdk/prod/custom/intents/listen_audiobook_lvl1.yaml rename to sdk/custom/intents/listen_audiobook_lvl1.yaml diff --git a/sdk/prod/custom/intents/listen_audiobook_lvl2.yaml b/sdk/custom/intents/listen_audiobook_lvl2.yaml similarity index 100% rename from sdk/prod/custom/intents/listen_audiobook_lvl2.yaml rename to sdk/custom/intents/listen_audiobook_lvl2.yaml diff --git a/sdk/test/custom/intents/listen_toc.yaml b/sdk/custom/intents/listen_toc.yaml similarity index 100% rename from sdk/test/custom/intents/listen_toc.yaml rename to sdk/custom/intents/listen_toc.yaml diff --git a/sdk/test/custom/intents/menu.yaml b/sdk/custom/intents/menu.yaml similarity index 100% rename from sdk/test/custom/intents/menu.yaml rename to sdk/custom/intents/menu.yaml diff --git a/sdk/test/custom/intents/next.yaml b/sdk/custom/intents/next.yaml similarity index 100% rename from sdk/test/custom/intents/next.yaml rename to sdk/custom/intents/next.yaml diff --git a/sdk/prod/custom/intents/no.yaml b/sdk/custom/intents/no.yaml similarity index 100% rename from sdk/prod/custom/intents/no.yaml rename to sdk/custom/intents/no.yaml diff --git a/sdk/prod/custom/intents/remaing_time_player.yaml b/sdk/custom/intents/remaing_time_player.yaml similarity index 100% rename from sdk/prod/custom/intents/remaing_time_player.yaml rename to sdk/custom/intents/remaing_time_player.yaml diff --git a/sdk/test/custom/intents/repeat.yaml b/sdk/custom/intents/repeat.yaml similarity index 100% rename from sdk/test/custom/intents/repeat.yaml rename to sdk/custom/intents/repeat.yaml diff --git a/sdk/test/custom/intents/resume_audiobook_lvl2.yaml b/sdk/custom/intents/resume_audiobook_lvl2.yaml similarity index 100% rename from sdk/test/custom/intents/resume_audiobook_lvl2.yaml rename to sdk/custom/intents/resume_audiobook_lvl2.yaml diff --git a/sdk/test/custom/intents/resume_listening_player.yaml b/sdk/custom/intents/resume_listening_player.yaml similarity index 100% rename from sdk/test/custom/intents/resume_listening_player.yaml rename to sdk/custom/intents/resume_listening_player.yaml diff --git a/sdk/test/custom/intents/selection_all_publication_lvl3.yaml b/sdk/custom/intents/selection_all_publication_lvl3.yaml similarity index 100% rename from sdk/test/custom/intents/selection_all_publication_lvl3.yaml rename to sdk/custom/intents/selection_all_publication_lvl3.yaml diff --git a/sdk/prod/custom/intents/selection_audiobook_lvl2.yaml b/sdk/custom/intents/selection_audiobook_lvl2.yaml similarity index 100% rename from sdk/prod/custom/intents/selection_audiobook_lvl2.yaml rename to sdk/custom/intents/selection_audiobook_lvl2.yaml diff --git a/sdk/prod/custom/intents/selection_genre_lvl3.yaml b/sdk/custom/intents/selection_genre_lvl3.yaml similarity index 100% rename from sdk/prod/custom/intents/selection_genre_lvl3.yaml rename to sdk/custom/intents/selection_genre_lvl3.yaml diff --git a/sdk/prod/custom/intents/selection_my_list_lvl3.yaml b/sdk/custom/intents/selection_my_list_lvl3.yaml similarity index 100% rename from sdk/prod/custom/intents/selection_my_list_lvl3.yaml rename to sdk/custom/intents/selection_my_list_lvl3.yaml diff --git a/sdk/prod/custom/intents/selection_thematic_list_lvl3.yaml b/sdk/custom/intents/selection_thematic_list_lvl3.yaml similarity index 100% rename from sdk/prod/custom/intents/selection_thematic_list_lvl3.yaml rename to sdk/custom/intents/selection_thematic_list_lvl3.yaml diff --git a/sdk/test/custom/intents/stop.yaml b/sdk/custom/intents/stop.yaml similarity index 100% rename from sdk/test/custom/intents/stop.yaml rename to sdk/custom/intents/stop.yaml diff --git a/sdk/test/custom/intents/test_player_sdk.yaml b/sdk/custom/intents/test_player_sdk.yaml similarity index 100% rename from sdk/test/custom/intents/test_player_sdk.yaml rename to sdk/custom/intents/test_player_sdk.yaml diff --git a/sdk/test/custom/intents/test_setup_sdk.yaml b/sdk/custom/intents/test_setup_sdk.yaml similarity index 100% rename from sdk/test/custom/intents/test_setup_sdk.yaml rename to sdk/custom/intents/test_setup_sdk.yaml diff --git a/sdk/prod/custom/intents/test_webhook.yaml b/sdk/custom/intents/test_webhook.yaml similarity index 100% rename from sdk/prod/custom/intents/test_webhook.yaml rename to sdk/custom/intents/test_webhook.yaml diff --git a/sdk/prod/custom/intents/yes.yaml b/sdk/custom/intents/yes.yaml similarity index 100% rename from sdk/prod/custom/intents/yes.yaml rename to sdk/custom/intents/yes.yaml diff --git a/sdk/test/custom/scenes/ask_to_resume_listening_at_last_offset.yaml b/sdk/custom/scenes/ask_to_resume_listening_at_last_offset.yaml similarity index 100% rename from sdk/test/custom/scenes/ask_to_resume_listening_at_last_offset.yaml rename to sdk/custom/scenes/ask_to_resume_listening_at_last_offset.yaml diff --git a/sdk/test/custom/scenes/home_lvl1.yaml b/sdk/custom/scenes/home_lvl1.yaml similarity index 100% rename from sdk/test/custom/scenes/home_lvl1.yaml rename to sdk/custom/scenes/home_lvl1.yaml diff --git a/sdk/prod/custom/scenes/home_lvl1_AccountLinking.yaml b/sdk/custom/scenes/home_lvl1_AccountLinking.yaml similarity index 100% rename from sdk/prod/custom/scenes/home_lvl1_AccountLinking.yaml rename to sdk/custom/scenes/home_lvl1_AccountLinking.yaml diff --git a/sdk/test/custom/scenes/home_members_lvl2.yaml b/sdk/custom/scenes/home_members_lvl2.yaml similarity index 100% rename from sdk/test/custom/scenes/home_members_lvl2.yaml rename to sdk/custom/scenes/home_members_lvl2.yaml diff --git a/sdk/test/custom/scenes/player.yaml b/sdk/custom/scenes/player.yaml similarity index 100% rename from sdk/test/custom/scenes/player.yaml rename to sdk/custom/scenes/player.yaml diff --git a/sdk/test/custom/scenes/player_toc.yaml b/sdk/custom/scenes/player_toc.yaml similarity index 100% rename from sdk/test/custom/scenes/player_toc.yaml rename to sdk/custom/scenes/player_toc.yaml diff --git a/sdk/test/custom/scenes/search.yaml b/sdk/custom/scenes/search.yaml similarity index 100% rename from sdk/test/custom/scenes/search.yaml rename to sdk/custom/scenes/search.yaml diff --git a/sdk/test/custom/scenes/select_group.yaml b/sdk/custom/scenes/select_group.yaml similarity index 100% rename from sdk/test/custom/scenes/select_group.yaml rename to sdk/custom/scenes/select_group.yaml diff --git a/sdk/test/custom/scenes/select_publication.yaml b/sdk/custom/scenes/select_publication.yaml similarity index 100% rename from sdk/test/custom/scenes/select_publication.yaml rename to sdk/custom/scenes/select_publication.yaml diff --git a/sdk/test/custom/scenes/selection_lvl3.yaml b/sdk/custom/scenes/selection_lvl3.yaml similarity index 100% rename from sdk/test/custom/scenes/selection_lvl3.yaml rename to sdk/custom/scenes/selection_lvl3.yaml diff --git a/sdk/prod/custom/types/string.yaml b/sdk/custom/types/string.yaml similarity index 100% rename from sdk/prod/custom/types/string.yaml rename to sdk/custom/types/string.yaml diff --git a/sdk/prod/manifest.yaml b/sdk/manifest.yaml similarity index 100% rename from sdk/prod/manifest.yaml rename to sdk/manifest.yaml diff --git a/sdk/prod/actions/actions.yaml b/sdk/prod/actions/actions.yaml deleted file mode 100644 index f82f9c46..00000000 --- a/sdk/prod/actions/actions.yaml +++ /dev/null @@ -1,2 +0,0 @@ -custom: - actions.intent.MAIN: {} diff --git a/sdk/prod/custom/global/actions.intent.MAIN.yaml b/sdk/prod/custom/global/actions.intent.MAIN.yaml deleted file mode 100644 index 463025af..00000000 --- a/sdk/prod/custom/global/actions.intent.MAIN.yaml +++ /dev/null @@ -1,9 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Bienvenue dans l'application d'écoute de livre audio valentin - hauy -transitionToScene: home_lvl1 diff --git a/sdk/prod/custom/intents/resume_audiobook_lvl2.yaml b/sdk/prod/custom/intents/resume_audiobook_lvl2.yaml deleted file mode 100644 index aab5315b..00000000 --- a/sdk/prod/custom/intents/resume_audiobook_lvl2.yaml +++ /dev/null @@ -1,15 +0,0 @@ -parameters: -- name: number1 - type: - name: actions.type.Number -trainingPhrases: -- lecture d'($number1 'un' auto=true) livre -- lecture de mon livre -- lecture -- lis ($number1 'un' auto=true) livre -- lis mon livre -- reprend la lecture de mon dernier livre -- reprendre l'écoute -- reprendre la lecture de mon dernier livre -- reprend la lecture -- reprendre la lecture diff --git a/sdk/prod/custom/intents/resume_listening_player.yaml b/sdk/prod/custom/intents/resume_listening_player.yaml deleted file mode 100644 index 2cd0b674..00000000 --- a/sdk/prod/custom/intents/resume_listening_player.yaml +++ /dev/null @@ -1,3 +0,0 @@ -trainingPhrases: -- reprend la lecture -- reprendre la lecture diff --git a/sdk/prod/custom/scenes/ask_to_resume_listening_at_last_offset.yaml b/sdk/prod/custom/scenes/ask_to_resume_listening_at_last_offset.yaml deleted file mode 100644 index c575375b..00000000 --- a/sdk/prod/custom/scenes/ask_to_resume_listening_at_last_offset.yaml +++ /dev/null @@ -1,11 +0,0 @@ -intentEvents: -- handler: - webhookHandler: ask_to_resume_listening_at_last_offset__yes - intent: "yes" - transitionToScene: player -- handler: - webhookHandler: ask_to_resume_listening_at_last_offset__no - intent: "no" - transitionToScene: player -onEnter: - webhookHandler: ask_to_resume_listening_at_last_offset diff --git a/sdk/prod/custom/scenes/home_lvl1.yaml b/sdk/prod/custom/scenes/home_lvl1.yaml deleted file mode 100644 index 4bf88a05..00000000 --- a/sdk/prod/custom/scenes/home_lvl1.yaml +++ /dev/null @@ -1,31 +0,0 @@ -intentEvents: -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Voici les informations sur l'association - intent: get_info_association_lvl1 - transitionToScene: home_lvl1 -- intent: enter_member_space_lvl1 - transitionToScene: home_lvl1_AccountLinking -- intent: resume_listening_player - transitionToScene: home_lvl1 -- intent: listen_audiobook_lvl1 - transitionToScene: home_lvl1_AccountLinking -- handler: - webhookHandler: test_webhook - intent: test_webhook - transitionToScene: home_lvl1 -onEnter: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Que voulez-vous faire ? Vous pouvez dire informations ou espace - membres - suggestions: - - title: informations - - title: espace membres diff --git a/sdk/prod/custom/scenes/home_members_lvl2.yaml b/sdk/prod/custom/scenes/home_members_lvl2.yaml deleted file mode 100644 index 2498e69c..00000000 --- a/sdk/prod/custom/scenes/home_members_lvl2.yaml +++ /dev/null @@ -1,25 +0,0 @@ -intentEvents: -- handler: - webhookHandler: ecouter_livre_audio_lvl2 - intent: listen_audiobook_lvl2 - transitionToScene: search -- handler: - webhookHandler: reprendre_mon_livre_lvl2 - intent: resume_audiobook_lvl2 - transitionToScene: ask_to_resume_listening_at_last_offset -- handler: - webhookHandler: selection_livre_lvl2 - intent: selection_audiobook_lvl2 - transitionToScene: selection_lvl3 -onEnter: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Bienvenue dans l'espace membres. Les commandes possibles sont, - sélection, lecture, recherche. Que voulez-vous faire ? - suggestions: - - title: selection d'un livre - - title: lecture du dernier livre - - title: recherche d'un livre diff --git a/sdk/prod/custom/scenes/player.yaml b/sdk/prod/custom/scenes/player.yaml deleted file mode 100644 index 06957f78..00000000 --- a/sdk/prod/custom/scenes/player.yaml +++ /dev/null @@ -1,21 +0,0 @@ -intentEvents: -- handler: - webhookHandler: reprendre_la_lecture - intent: resume_listening_player -- handler: - webhookHandler: remaining_time - intent: remaing_time_player -- handler: - webhookHandler: media_status - intent: actions.intent.MEDIA_STATUS_FINISHED -- handler: - webhookHandler: media_status - intent: actions.intent.MEDIA_STATUS_PAUSED -- handler: - webhookHandler: media_status - intent: actions.intent.MEDIA_STATUS_STOPPED -- handler: - webhookHandler: media_status - intent: actions.intent.MEDIA_STATUS_FAILED -onEnter: - webhookHandler: player diff --git a/sdk/prod/custom/scenes/search.yaml b/sdk/prod/custom/scenes/search.yaml deleted file mode 100644 index 4d95c236..00000000 --- a/sdk/prod/custom/scenes/search.yaml +++ /dev/null @@ -1,21 +0,0 @@ -conditionalEvents: -- condition: scene.slots.status == "FINAL" - handler: - webhookHandler: search_livre_lvl2 -intentEvents: -- intent: resume_listening_player - transitionToScene: search -onEnter: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Que voulez-vous écouter ? Par exemple Zola -slots: -- commitBehavior: - writeSessionParam: query - name: query - required: true - type: - name: string diff --git a/sdk/prod/custom/scenes/select_pub_after_search.yaml b/sdk/prod/custom/scenes/select_pub_after_search.yaml deleted file mode 100644 index f6dc9f7b..00000000 --- a/sdk/prod/custom/scenes/select_pub_after_search.yaml +++ /dev/null @@ -1,69 +0,0 @@ -intentEvents: -- intent: resume_listening_player - transitionToScene: select_pub_after_search -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, merci de le répêter - intent: actions.intent.NO_MATCH_1 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, dite un numéro - intent: actions.intent.NO_MATCH_2 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro. - intent: actions.intent.NO_MATCH_FINAL - transitionToScene: search -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, merci de le répêter - intent: actions.intent.NO_INPUT_1 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, merci de le répêter - intent: actions.intent.NO_INPUT_2 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro - intent: actions.intent.NO_INPUT_FINAL - transitionToScene: search -onEnter: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Pour choisir une publication dite son numéro -onSlotUpdated: - webhookHandler: select_publication_number_after_search -slots: -- commitBehavior: - writeSessionParam: number - name: number - required: true - type: - name: actions.type.Number diff --git a/sdk/prod/custom/scenes/select_pub_after_selection.yaml b/sdk/prod/custom/scenes/select_pub_after_selection.yaml deleted file mode 100644 index 10d12712..00000000 --- a/sdk/prod/custom/scenes/select_pub_after_selection.yaml +++ /dev/null @@ -1,67 +0,0 @@ -intentEvents: -- intent: resume_listening_player - transitionToScene: select_pub_after_selection -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, merci de le répêter - intent: actions.intent.NO_MATCH_1 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, dite un numéro - intent: actions.intent.NO_MATCH_2 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, dite un numéro - intent: actions.intent.NO_MATCH_FINAL -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, dite un numéro - intent: actions.intent.NO_INPUT_1 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, dite un numéro - intent: actions.intent.NO_INPUT_2 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro - intent: actions.intent.NO_INPUT_FINAL -onEnter: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Pour choisir une publication dite son numéro -onSlotUpdated: - webhookHandler: select_publication_number_after_selection -slots: -- commitBehavior: - writeSessionParam: number - name: number - required: true - type: - name: actions.type.Number diff --git a/sdk/prod/custom/scenes/selection_lvl3.yaml b/sdk/prod/custom/scenes/selection_lvl3.yaml deleted file mode 100644 index 583e652a..00000000 --- a/sdk/prod/custom/scenes/selection_lvl3.yaml +++ /dev/null @@ -1,10 +0,0 @@ -intentEvents: -- handler: - webhookHandler: selection_genre_lvl3 - intent: selection_genre_lvl3 -- handler: - webhookHandler: selection_thematic_list_lvl3 - intent: selection_thematic_list_lvl3 -- handler: - webhookHandler: selection_my_list_lvl3 - intent: selection_my_list_lvl3 diff --git a/sdk/prod/settings/settings.yaml b/sdk/prod/settings/settings.yaml deleted file mode 100644 index 3e43f2a0..00000000 --- a/sdk/prod/settings/settings.yaml +++ /dev/null @@ -1,24 +0,0 @@ -accountLinking: - appClientId: "1232456" - authGrantType: IMPLICIT - authorizationUrl: https://opds-auth-test-server-aplqpqv3wa-ey.a.run.app/implicit/login?lang=fr - linkingType: OAUTH -category: EDUCATION_AND_REFERENCE -defaultLocale: fr -localizedSettings: - developerEmail: dev.edrlab@gmail.com - developerName: edrlab - displayName: valentin audio - fullDescription: lis mon live edrlab demo - privacyPolicyUrl: https://www.edrlab.org/lml-privacy-policy/ - pronunciation: valentin audio - sampleInvocations: - - Parler avec valentin audio - - Connecter avec valentin audio - - Discuter avec valentin audio - shortDescription: lis mon livre - smallLogoImage: https://lh3.googleusercontent.com/IPE84cRJZSbgpkLCNMhJFkP_sbh5e18cYRvn30hVHE6nYNLfQ_9a-opqTKbQNThVPUzo8sfP1_cR - voice: female_1 -projectId: valentin-4 -testingInstructions: "login: \n\nadmin\nadmin\n\nyou can test with the query \"zola\" - or \"la guerre des boutons\"" diff --git a/sdk/prod/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/prod/webhooks/ActionsOnGoogleFulfillment.yaml deleted file mode 100644 index 814e3d4d..00000000 --- a/sdk/prod/webhooks/ActionsOnGoogleFulfillment.yaml +++ /dev/null @@ -1,22 +0,0 @@ -handlers: -- name: cancel -- name: ecouter_livre_audio_lvl2 -- name: reprendre_mon_livre_lvl2 -- name: media_status -- name: player -- name: reprendre_la_lecture -- name: remaining_time -- name: selection_livre_lvl2 -- name: select_publication_number_after_search -- name: select_publication_number_after_selection -- name: test_webhook -- name: search_livre_lvl2 -- name: ask_to_resume_listening_at_last_offset -- name: ask_to_resume_listening_at_last_offset__yes -- name: ask_to_resume_listening_at_last_offset__no -- name: selection_genre_lvl3 -- name: selection_thematic_list_lvl3 -- name: selection_my_list_lvl3 -httpsEndpoint: - baseUrl: https://us-central1-valentin-4.cloudfunctions.net/ActionsOnGoogleFulfillment - endpointApiVersion: 2 diff --git a/sdk/test/settings/settings.yaml b/sdk/settings/settings.yaml similarity index 68% rename from sdk/test/settings/settings.yaml rename to sdk/settings/settings.yaml index 3448ec21..cc631e71 100644 --- a/sdk/test/settings/settings.yaml +++ b/sdk/settings/settings.yaml @@ -3,15 +3,15 @@ defaultLocale: fr localizedSettings: developerEmail: dev.edrlab@gmail.com developerName: edrlab - displayName: valentin audio dev + displayName: dev edrlab fullDescription: lis mon live edrlab demo privacyPolicyUrl: https://www.edrlab.org/lml-privacy-policy/ - pronunciation: valentin audio dev + pronunciation: dev edrlab sampleInvocations: - - Parler avec valentin audio dev - - Connecter avec valentin audio dev - - Discuter avec valentin audio dev + - Parler avec edrlab + - Connecter avec edrlab + - Discuter avec edrlab shortDescription: lis mon livre smallLogoImage: https://lh3.googleusercontent.com/IPE84cRJZSbgpkLCNMhJFkP_sbh5e18cYRvn30hVHE6nYNLfQ_9a-opqTKbQNThVPUzo8sfP1_cR voice: female_1 -projectId: valentin-5 +projectId: edrlab-1 diff --git a/sdk/test/custom/global/actions.intent.CANCEL.yaml b/sdk/test/custom/global/actions.intent.CANCEL.yaml deleted file mode 100644 index 22c095fb..00000000 --- a/sdk/test/custom/global/actions.intent.CANCEL.yaml +++ /dev/null @@ -1,9 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Au revoir et a bientôt - webhookHandler: cancel -transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/test/custom/global/actions.intent.NO_INPUT_1.yaml b/sdk/test/custom/global/actions.intent.NO_INPUT_1.yaml deleted file mode 100644 index de975f82..00000000 --- a/sdk/test/custom/global/actions.intent.NO_INPUT_1.yaml +++ /dev/null @@ -1,7 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n'ai pas entendu. Que voulez-vous dire ? diff --git a/sdk/test/custom/global/actions.intent.NO_INPUT_2.yaml b/sdk/test/custom/global/actions.intent.NO_INPUT_2.yaml deleted file mode 100644 index 59e57245..00000000 --- a/sdk/test/custom/global/actions.intent.NO_INPUT_2.yaml +++ /dev/null @@ -1,7 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Que dite-vous ? diff --git a/sdk/test/custom/global/actions.intent.NO_INPUT_FINAL.yaml b/sdk/test/custom/global/actions.intent.NO_INPUT_FINAL.yaml deleted file mode 100644 index 63087279..00000000 --- a/sdk/test/custom/global/actions.intent.NO_INPUT_FINAL.yaml +++ /dev/null @@ -1,8 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Je quitte l'application -transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/test/custom/global/actions.intent.NO_MATCH_1.yaml b/sdk/test/custom/global/actions.intent.NO_MATCH_1.yaml deleted file mode 100644 index 166efc70..00000000 --- a/sdk/test/custom/global/actions.intent.NO_MATCH_1.yaml +++ /dev/null @@ -1,7 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n'ai pas compris. Que voulez-vous dire ? diff --git a/sdk/test/custom/global/actions.intent.NO_MATCH_2.yaml b/sdk/test/custom/global/actions.intent.NO_MATCH_2.yaml deleted file mode 100644 index deda0dc7..00000000 --- a/sdk/test/custom/global/actions.intent.NO_MATCH_2.yaml +++ /dev/null @@ -1,7 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n'ai vraiment pas compris. Que voulez-vous dire ? diff --git a/sdk/test/custom/global/actions.intent.NO_MATCH_FINAL.yaml b/sdk/test/custom/global/actions.intent.NO_MATCH_FINAL.yaml deleted file mode 100644 index 2f8cf92a..00000000 --- a/sdk/test/custom/global/actions.intent.NO_MATCH_FINAL.yaml +++ /dev/null @@ -1,8 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: malheureusement je m'en vais, je ne comprend pas -transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/test/custom/intents/enter_member_space_lvl1.yaml b/sdk/test/custom/intents/enter_member_space_lvl1.yaml deleted file mode 100644 index b61cfd70..00000000 --- a/sdk/test/custom/intents/enter_member_space_lvl1.yaml +++ /dev/null @@ -1,5 +0,0 @@ -trainingPhrases: -- espace maman -- membres -- espace membres -- Je veux entrer dans l'espace membres diff --git a/sdk/test/custom/intents/get_info_association_lvl1.yaml b/sdk/test/custom/intents/get_info_association_lvl1.yaml deleted file mode 100644 index 837e0830..00000000 --- a/sdk/test/custom/intents/get_info_association_lvl1.yaml +++ /dev/null @@ -1,4 +0,0 @@ -trainingPhrases: -- informations -- obtenir des informations -- Je veux obtenir des informations sur l'association diff --git a/sdk/test/custom/intents/i_want_to_listen_lvl3.yaml b/sdk/test/custom/intents/i_want_to_listen_lvl3.yaml deleted file mode 100644 index aa4c1c81..00000000 --- a/sdk/test/custom/intents/i_want_to_listen_lvl3.yaml +++ /dev/null @@ -1,10 +0,0 @@ -parameters: -- name: query - type: - name: string -trainingPhrases: -- ($query 'le nom du livre suivi de l\'auteur' auto=false) -- je veux écouter ($query 'cyrano de Bergerac d\'Edmond Rostand' auto=false) -- je veux écouter ($query 'le rouge et le noir de stendhall' auto=false) -- je veux écouter ($query 'le rouge et le noir' auto=false) -- je veux écouter ($query 'la chartreuse de parme' auto=false) diff --git a/sdk/test/custom/intents/listen_audiobook_lvl1.yaml b/sdk/test/custom/intents/listen_audiobook_lvl1.yaml deleted file mode 100644 index 5ee4919f..00000000 --- a/sdk/test/custom/intents/listen_audiobook_lvl1.yaml +++ /dev/null @@ -1,6 +0,0 @@ -trainingPhrases: -- recherche d'un livre -- recherche -- rechercher ($number1 'un' auto=true) livre -- écouter un livre -- je veux écouter un livre diff --git a/sdk/test/custom/intents/listen_audiobook_lvl2.yaml b/sdk/test/custom/intents/listen_audiobook_lvl2.yaml deleted file mode 100644 index 61fb43ec..00000000 --- a/sdk/test/custom/intents/listen_audiobook_lvl2.yaml +++ /dev/null @@ -1,12 +0,0 @@ -trainingPhrases: -- recherche d'un livre -- recherche -- rechercher ($number1 'un' auto=true) livre -- je veux écouter -- je veux écouter un livre -- écouter -- livre audio -- livre -- écouter u($number1 'n ' auto=true)audiobook -- écouter un livre -- écouter un livre audio diff --git a/sdk/test/custom/intents/no.yaml b/sdk/test/custom/intents/no.yaml deleted file mode 100644 index 873ac739..00000000 --- a/sdk/test/custom/intents/no.yaml +++ /dev/null @@ -1,5 +0,0 @@ -trainingPhrases: -- "n" -- non -- "no" -- nop diff --git a/sdk/test/custom/intents/remaing_time_player.yaml b/sdk/test/custom/intents/remaing_time_player.yaml deleted file mode 100644 index 703f8de9..00000000 --- a/sdk/test/custom/intents/remaing_time_player.yaml +++ /dev/null @@ -1,7 +0,0 @@ -trainingPhrases: -- combien de temps de lecture me restent-t-il ? -- depuis combien de temps j'écoute ce livre ? -- dis-moi le temps de lecture -- donne moi le temps de lecture -- quel temps me reste-t-il ? -- combien de temps de lecture reste-t-il ? diff --git a/sdk/test/custom/intents/selection_audiobook_lvl2.yaml b/sdk/test/custom/intents/selection_audiobook_lvl2.yaml deleted file mode 100644 index f07b780e..00000000 --- a/sdk/test/custom/intents/selection_audiobook_lvl2.yaml +++ /dev/null @@ -1,5 +0,0 @@ -trainingPhrases: -- ma liste de lecture -- liste de lecture -- selection d'($number1 'un' auto=true) livre -- selection diff --git a/sdk/test/custom/intents/selection_genre_lvl3.yaml b/sdk/test/custom/intents/selection_genre_lvl3.yaml deleted file mode 100644 index 63195424..00000000 --- a/sdk/test/custom/intents/selection_genre_lvl3.yaml +++ /dev/null @@ -1,4 +0,0 @@ -trainingPhrases: -- je veux la sélection par genre -- genre -- sélection par genre diff --git a/sdk/test/custom/intents/selection_my_list_lvl3.yaml b/sdk/test/custom/intents/selection_my_list_lvl3.yaml deleted file mode 100644 index 020db8d6..00000000 --- a/sdk/test/custom/intents/selection_my_list_lvl3.yaml +++ /dev/null @@ -1,4 +0,0 @@ -trainingPhrases: -- je veux ma liste -- ma liste de lecture -- ma liste diff --git a/sdk/test/custom/intents/selection_thematic_list_lvl3.yaml b/sdk/test/custom/intents/selection_thematic_list_lvl3.yaml deleted file mode 100644 index 5ff3b4b0..00000000 --- a/sdk/test/custom/intents/selection_thematic_list_lvl3.yaml +++ /dev/null @@ -1,4 +0,0 @@ -trainingPhrases: -- sélection thématique -- je veux la liste thématique -- liste thématique diff --git a/sdk/test/custom/intents/test_webhook.yaml b/sdk/test/custom/intents/test_webhook.yaml deleted file mode 100644 index b955a43c..00000000 --- a/sdk/test/custom/intents/test_webhook.yaml +++ /dev/null @@ -1,3 +0,0 @@ -trainingPhrases: -- test -- test webhook diff --git a/sdk/test/custom/intents/yes.yaml b/sdk/test/custom/intents/yes.yaml deleted file mode 100644 index 92072da0..00000000 --- a/sdk/test/custom/intents/yes.yaml +++ /dev/null @@ -1,6 +0,0 @@ -trainingPhrases: -- "y" -- ui -- ouep -- ouais -- oui diff --git a/sdk/test/custom/scenes/home_lvl1_AccountLinking.yaml b/sdk/test/custom/scenes/home_lvl1_AccountLinking.yaml deleted file mode 100644 index a3fb2cf1..00000000 --- a/sdk/test/custom/scenes/home_lvl1_AccountLinking.yaml +++ /dev/null @@ -1,19 +0,0 @@ -conditionalEvents: -- condition: session.params.AccountLinkingSlot == "LINKED" - transitionToScene: home_members_lvl2 -- condition: session.params.AccountLinkingSlot == "ERROR" - transitionToScene: home_lvl1 -- condition: session.params.AccountLinkingSlot == "REJECTED" - transitionToScene: home_lvl1 -slots: -- commitBehavior: - writeSessionParam: AccountLinkingSlot - config: - '@type': type.googleapis.com/google.actions.conversation.v3.SignInSpec - opt_context: "" - defaultValue: - sessionParam: AccountLinkingSlot - name: AccountLinkingSlot - required: true - type: - name: actions.type.AccountLinking diff --git a/sdk/test/custom/types/string.yaml b/sdk/test/custom/types/string.yaml deleted file mode 100644 index 63ddd907..00000000 --- a/sdk/test/custom/types/string.yaml +++ /dev/null @@ -1 +0,0 @@ -freeText: {} diff --git a/sdk/test/manifest.yaml b/sdk/test/manifest.yaml deleted file mode 100644 index d847aecb..00000000 --- a/sdk/test/manifest.yaml +++ /dev/null @@ -1 +0,0 @@ -version: "1.0" diff --git a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml similarity index 95% rename from sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml rename to sdk/webhooks/ActionsOnGoogleFulfillment.yaml index f2c5258a..e69c4449 100644 --- a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -46,5 +46,5 @@ handlers: - name: player_toc__slot__number - name: player__intent__listen_toc httpsEndpoint: - baseUrl: https://us-central1-valentin-5.cloudfunctions.net/ActionsOnGoogleFulfillment + baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/test/dev/.eslintrc.json b/test/.eslintrc.json similarity index 100% rename from test/dev/.eslintrc.json rename to test/.eslintrc.json diff --git a/test/dev/package-lock.json b/test/package-lock.json similarity index 100% rename from test/dev/package-lock.json rename to test/package-lock.json diff --git a/test/dev/package.json b/test/package.json similarity index 100% rename from test/dev/package.json rename to test/package.json diff --git a/test/prod/.eslintrc.json b/test/prod/.eslintrc.json deleted file mode 100644 index c5624c4e..00000000 --- a/test/prod/.eslintrc.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "env": { - "browser": true, - "es2021": true - }, - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": 12, - "sourceType": "module" - }, - "plugins": [ - "@typescript-eslint" - ], - "rules": { - } -} diff --git a/test/prod/package-lock.json b/test/prod/package-lock.json deleted file mode 100644 index be66871b..00000000 --- a/test/prod/package-lock.json +++ /dev/null @@ -1,3161 +0,0 @@ -{ - "name": "lis-mon-livre-test", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@assistant/actions": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@assistant/actions/-/actions-0.1.0.tgz", - "integrity": "sha512-V3PUGj7j/8Gq4VPFwP40k6AnsJaV2nnViuGskYnCe8sKLgCTzeGsOKnoGJgEEjI3ETm5mPd8ym3/HoksRODMNw==", - "dev": true, - "requires": { - "google-gax": "^2.9.2" - } - }, - "@assistant/conversation-testing": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@assistant/conversation-testing/-/conversation-testing-1.0.0.tgz", - "integrity": "sha512-9NZ3q1PI/FXegVaF+Kt2M/z2tWcDSPZ8aQ/UBYqtmYk0xSQX3ZRNhg9FWEGeAGL7+1tV4aRRkBylTvUUOGivrQ==", - "dev": true, - "requires": { - "@assistant/actions": "0.1.0", - "@types/chai": "^4.1.4", - "@types/i18n": "^0.8.6", - "@types/js-yaml": "^3.12.5", - "@types/node": "^10.9.4", - "@types/promise.prototype.finally": "^2.0.3", - "chai": "^4.2.0", - "google-auth-library": "^6.1.2", - "grpc": "^1.24.0", - "i18n": "^0.8.3", - "js-yaml": "^3.14.0", - "promise.prototype.finally": "^3.1.1", - "ts-node": "^7.0.1" - }, - "dependencies": { - "@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - } - } - } - }, - "@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true - }, - "@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", - "dev": true, - "requires": { - "@cspotcode/source-map-consumer": "0.8.0" - } - }, - "@eslint/eslintrc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.3.tgz", - "integrity": "sha512-DHI1wDPoKCBPoLZA3qDR91+3te/wDSc1YhKg3jR8NxKKRJq2hwHwcWv31cSwSYvIBrmbENoYMWcenW8uproQqg==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.0.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - } - }, - "@grpc/grpc-js": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.4.1.tgz", - "integrity": "sha512-/chkA48TdAvATHA7RXJPeHQLdfFhpu51974s8htjO/XTDHA41j5+SkR5Io+lr9XsLmkZD6HxLyRAFGmA9wjO2w==", - "dev": true, - "requires": { - "@grpc/proto-loader": "^0.6.4", - "@types/node": ">=12.12.47" - } - }, - "@grpc/proto-loader": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.6.tgz", - "integrity": "sha512-cdMaPZ8AiFz6ua6PUbP+LKbhwJbFXnrQ/mlnKGUyzDUZ3wp7vPLksnmLCBX6SHgSmjX7CbNVNLFYD5GmmjO4GQ==", - "dev": true, - "requires": { - "@types/long": "^4.0.1", - "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", - "protobufjs": "^6.10.0", - "yargs": "^16.1.1" - } - }, - "@humanwhocodes/config-array": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.6.0.tgz", - "integrity": "sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", - "dev": true - }, - "@mapbox/node-pre-gyp": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.6.tgz", - "integrity": "sha512-qK1ECws8UxuPqOA8F5LFD90vyVU33W7N3hGfgsOVfrJaRVc8McC3JClTDHpeSbL9CBrOHly/4GsNPAvIgNZE+g==", - "dev": true, - "requires": { - "detect-libc": "^1.0.3", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.5", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=", - "dev": true - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "dev": true - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "dev": true - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=", - "dev": true - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "dev": true, - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=", - "dev": true - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=", - "dev": true - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=", - "dev": true - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=", - "dev": true - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", - "dev": true - }, - "@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", - "dev": true - }, - "@types/bytebuffer": { - "version": "5.0.42", - "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.42.tgz", - "integrity": "sha512-lEgKojWUAc/MG2t649oZS5AfYFP2xRNPoDuwDBlBMjHXd8MaGPgFgtCXUK7inZdBOygmVf10qxc1Us8GXC96aw==", - "dev": true, - "requires": { - "@types/long": "*", - "@types/node": "*" - } - }, - "@types/chai": { - "version": "4.2.22", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.22.tgz", - "integrity": "sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ==", - "dev": true - }, - "@types/i18n": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@types/i18n/-/i18n-0.8.8.tgz", - "integrity": "sha512-RI4LFAraGrimMTxXkediCMXGVLC6ksXIIo3U+d3E4n+Mhw3uIDbmokO7DHlPB/eu6Tn6KBv4IUE1WrrEDRdNUQ==", - "dev": true - }, - "@types/js-yaml": { - "version": "3.12.7", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.7.tgz", - "integrity": "sha512-S6+8JAYTE1qdsc9HMVsfY7+SgSuUU/Tp6TYTmITW0PZxiyIMvol3Gy//y69Wkhs0ti4py5qgR3uZH6uz/DNzJQ==", - "dev": true - }, - "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true - }, - "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==", - "dev": true - }, - "@types/mocha": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.0.0.tgz", - "integrity": "sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==", - "dev": true - }, - "@types/node": { - "version": "16.11.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.4.tgz", - "integrity": "sha512-TMgXmy0v2xWyuCSCJM6NCna2snndD8yvQF67J29ipdzMcsPa9u+o0tjF5+EQNdhcuZplYuouYqpc4zcd5I6amQ==", - "dev": true - }, - "@types/promise.prototype.finally": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/promise.prototype.finally/-/promise.prototype.finally-2.0.4.tgz", - "integrity": "sha512-bkzsMz11tGI5r/ZhJIVI1+QSWKKBcX/Llv0zoM2ufOH+o/3sLXwE5xCW0OUX81xPa4EGOyPKFlNrH9GH+IF4lg==", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.2.0.tgz", - "integrity": "sha512-qQwg7sqYkBF4CIQSyRQyqsYvP+g/J0To9ZPVNJpfxfekl5RmdvQnFFTVVwpRtaUDFNvjfe/34TgY/dpc3MgNTw==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "5.2.0", - "@typescript-eslint/scope-manager": "5.2.0", - "debug": "^4.3.2", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.2.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.2.0.tgz", - "integrity": "sha512-RW+wowZqPzQw8MUFltfKYZfKXqA2qgyi6oi/31J1zfXJRpOn6tCaZtd9b5u9ubnDG2n/EMvQLeZrsLNPpaUiFQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.2.0", - "@typescript-eslint/visitor-keys": "5.2.0" - } - }, - "@typescript-eslint/types": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.2.0.tgz", - "integrity": "sha512-cTk6x08qqosps6sPyP2j7NxyFPlCNsJwSDasqPNjEQ8JMD5xxj2NHxcLin5AJQ8pAVwpQ8BMI3bTxR0zxmK9qQ==", - "dev": true - }, - "@typescript-eslint/visitor-keys": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.2.0.tgz", - "integrity": "sha512-Nk7HizaXWWCUBfLA/rPNKMzXzWS8Wg9qHMuGtT+v2/YpPij4nVXrVJc24N/r5WrrmqK31jCrZxeHqIgqRzs0Xg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.2.0", - "eslint-visitor-keys": "^3.0.0" - } - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - } - } - }, - "@typescript-eslint/experimental-utils": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.2.0.tgz", - "integrity": "sha512-fWyT3Agf7n7HuZZRpvUYdFYbPk3iDCq6fgu3ulia4c7yxmPnwVBovdSOX7RL+k8u6hLbrXcdAehlWUVpGh6IEw==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.2.0", - "@typescript-eslint/types": "5.2.0", - "@typescript-eslint/typescript-estree": "5.2.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.2.0.tgz", - "integrity": "sha512-RW+wowZqPzQw8MUFltfKYZfKXqA2qgyi6oi/31J1zfXJRpOn6tCaZtd9b5u9ubnDG2n/EMvQLeZrsLNPpaUiFQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.2.0", - "@typescript-eslint/visitor-keys": "5.2.0" - } - }, - "@typescript-eslint/types": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.2.0.tgz", - "integrity": "sha512-cTk6x08qqosps6sPyP2j7NxyFPlCNsJwSDasqPNjEQ8JMD5xxj2NHxcLin5AJQ8pAVwpQ8BMI3bTxR0zxmK9qQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.2.0.tgz", - "integrity": "sha512-RsdXq2XmVgKbm9nLsE3mjNUM7BTr/K4DYR9WfFVMUuozHWtH5gMpiNZmtrMG8GR385EOSQ3kC9HiEMJWimxd/g==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.2.0", - "@typescript-eslint/visitor-keys": "5.2.0", - "debug": "^4.3.2", - "globby": "^11.0.4", - "is-glob": "^4.0.3", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.2.0.tgz", - "integrity": "sha512-Nk7HizaXWWCUBfLA/rPNKMzXzWS8Wg9qHMuGtT+v2/YpPij4nVXrVJc24N/r5WrrmqK31jCrZxeHqIgqRzs0Xg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.2.0", - "eslint-visitor-keys": "^3.0.0" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - } - } - }, - "@typescript-eslint/parser": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.1.0.tgz", - "integrity": "sha512-vx1P+mhCtYw3+bRHmbalq/VKP2Y3gnzNgxGxfEWc6OFpuEL7iQdAeq11Ke3Rhy8NjgB+AHsIWEwni3e+Y7djKA==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.1.0", - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/typescript-estree": "5.1.0", - "debug": "^4.3.2" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.1.0.tgz", - "integrity": "sha512-yYlyVjvn5lvwCL37i4hPsa1s0ORsjkauhTqbb8MnpvUs7xykmcjGqwlNZ2Q5QpoqkJ1odlM2bqHqJwa28qV6Tw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/visitor-keys": "5.1.0" - } - }, - "@typescript-eslint/types": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.1.0.tgz", - "integrity": "sha512-sEwNINVxcB4ZgC6Fe6rUyMlvsB2jvVdgxjZEjQUQVlaSPMNamDOwO6/TB98kFt4sYYfNhdhTPBEQqNQZjMMswA==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.1.0.tgz", - "integrity": "sha512-SSz+l9YrIIsW4s0ZqaEfnjl156XQ4VRmJsbA0ZE1XkXrD3cRpzuZSVCyqeCMR3EBjF27IisWakbBDGhGNIOvfQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/visitor-keys": "5.1.0", - "debug": "^4.3.2", - "globby": "^11.0.4", - "is-glob": "^4.0.3", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.1.0.tgz", - "integrity": "sha512-uqNXepKBg81JVwjuqAxYrXa1Ql/YDzM+8g/pS+TCPxba0wZttl8m5DkrasbfnmJGHs4lQ2jTbcZ5azGhI7kK+w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.1.0", - "eslint-visitor-keys": "^3.0.0" - } - }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true - }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "dev": true - }, - "are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - }, - "dependencies": { - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - } - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true - }, - "ascli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", - "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", - "dev": true, - "requires": { - "colour": "~0.7.1", - "optjs": "~3.2.2" - } - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", - "dev": true - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=", - "dev": true - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "bytebuffer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", - "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", - "dev": true, - "requires": { - "long": "~3" - }, - "dependencies": { - "long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", - "dev": true - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, - "colour": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz", - "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "dev": true, - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.1.0.tgz", - "integrity": "sha512-JZvNneArGSUsluHWJ8g8MMs3CfIEzwaLx9KyH4tZ2i+R2/rPWzL8c0zg3rHdwYVpN/1sB9gqnjHwz9HoeJpGHw==", - "dev": true, - "requires": { - "@eslint/eslintrc": "^1.0.3", - "@humanwhocodes/config-array": "^0.6.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^6.0.0", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.0.0", - "espree": "^9.0.0", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.2.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - } - } - }, - "eslint-scope": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-6.0.0.tgz", - "integrity": "sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz", - "integrity": "sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q==", - "dev": true - }, - "espree": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.0.0.tgz", - "integrity": "sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ==", - "dev": true, - "requires": { - "acorn": "^8.5.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.0.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fast-text-encoding": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", - "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==", - "dev": true - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", - "dev": true - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "gauge": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.1.tgz", - "integrity": "sha512-6STz6KdQgxO4S/ko+AbjlFGGdGcknluoqU+79GOFCDqqyYj5OanQf9AjxwN0jCidtT+ziPMmPSt9E4hfQ0CwIQ==", - "dev": true, - "requires": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1 || ^2.0.0", - "strip-ansi": "^3.0.1 || ^4.0.0", - "wide-align": "^1.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "gaxios": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.2.tgz", - "integrity": "sha512-T+ap6GM6UZ0c4E6yb1y/hy2UB6hTrqhglp3XfmU9qbLCGRYhLVV5aRPpC4EmoG8N8zOnkYCgoBz+ScvGAARY6Q==", - "dev": true, - "requires": { - "abort-controller": "^3.0.0", - "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.1" - } - }, - "gcp-metadata": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.1.tgz", - "integrity": "sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==", - "dev": true, - "requires": { - "gaxios": "^4.0.0", - "json-bigint": "^1.0.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "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" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - } - } - }, - "google-auth-library": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.6.tgz", - "integrity": "sha512-Q+ZjUEvLQj/lrVHF/IQwRo6p3s8Nc44Zk/DALsN+ac3T4HY/g/3rrufkgtl+nZ1TW7DNAw5cTChdVp4apUXVgQ==", - "dev": true, - "requires": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - } - }, - "google-gax": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.28.0.tgz", - "integrity": "sha512-kuqc8a4+CTCMBcF3tlOL7Sa74JWkTzcZxatAQTCVK35WToXkHnJ0qncFOJuegUv3EbV9IQY4j/+NZdFLv+lbTA==", - "dev": true, - "requires": { - "@grpc/grpc-js": "~1.4.0", - "@grpc/proto-loader": "^0.6.1", - "@types/long": "^4.0.0", - "abort-controller": "^3.0.0", - "duplexify": "^4.0.0", - "fast-text-encoding": "^1.0.3", - "google-auth-library": "^7.6.1", - "is-stream-ended": "^0.1.4", - "node-fetch": "^2.6.1", - "object-hash": "^2.1.1", - "proto3-json-serializer": "^0.1.1", - "protobufjs": "6.11.2", - "retry-request": "^4.0.0" - }, - "dependencies": { - "google-auth-library": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.10.1.tgz", - "integrity": "sha512-nQxgM1ZopUMcpMnu95kOSzI+9tJl4YDOZJomSTBGlRLpxfBopdwto7WvzoI87HuN0nQqVETgOsHi/C/po1rppA==", - "dev": true, - "requires": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - } - } - } - }, - "google-p12-pem": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.2.tgz", - "integrity": "sha512-tjf3IQIt7tWCDsa0ofDQ1qqSCNzahXDxdAGJDbruWqu3eCg5CKLYKN+hi0s6lfvzYZ1GDVr+oDF9OOWlDSdf0A==", - "dev": true, - "requires": { - "node-forge": "^0.10.0" - } - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "grpc": { - "version": "1.24.11", - "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.24.11.tgz", - "integrity": "sha512-8/AQdFCzCeCDWW3SoaMNp6ccbRvTQEH1O1u1uFtt29eWsg5gSZCJ3m6fbkduEIh3smY7WAPP+LgVJ5n3nZRxcA==", - "dev": true, - "requires": { - "@mapbox/node-pre-gyp": "^1.0.4", - "@types/bytebuffer": "^5.0.40", - "lodash.camelcase": "^4.3.0", - "lodash.clone": "^4.5.0", - "nan": "^2.13.2", - "protobufjs": "^5.0.3" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "protobufjs": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz", - "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==", - "dev": true, - "requires": { - "ascli": "~1", - "bytebuffer": "~5", - "glob": "^7.0.5", - "yargs": "^3.10.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", - "dev": true, - "requires": { - "camelcase": "^2.0.1", - "cliui": "^3.0.3", - "decamelize": "^1.1.1", - "os-locale": "^1.4.0", - "string-width": "^1.0.1", - "window-size": "^0.1.4", - "y18n": "^3.2.0" - } - } - } - }, - "gtoken": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.3.1.tgz", - "integrity": "sha512-yqOREjzLHcbzz1UrQoxhBtpk8KjrVhuqPE7od1K2uhyxG2BHjKZetlbLw/SPZak/QqTIQW+addS+EcjqQsZbwQ==", - "dev": true, - "requires": { - "gaxios": "^4.0.0", - "google-p12-pem": "^3.0.3", - "jws": "^4.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "i18n": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/i18n/-/i18n-0.8.6.tgz", - "integrity": "sha512-aMsJq8i1XXrb+BBsgmJBwak9mr69zPEIAUPb6c5yw2G/O4k1Q52lBxL+agZdQDN/RGf1ylQzrCswsOOgIiC1FA==", - "dev": true, - "requires": { - "debug": "*", - "make-plural": "^6.0.1", - "math-interval-parser": "^2.0.1", - "messageformat": "^2.3.0", - "mustache": "*", - "sprintf-js": "^1.1.2" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "is-stream-ended": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", - "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==", - "dev": true - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "is-weakref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "dev": true, - "requires": { - "bignumber.js": "^9.0.0" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "dev": true, - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "dev": true, - "requires": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", - "dev": true - }, - "lodash.clone": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", - "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "make-plural": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-6.2.2.tgz", - "integrity": "sha512-8iTuFioatnTTmb/YJjywkVIHLjcwkFD9Ms0JpxjEm9Mo8eQYkh1z+55dwv4yc1jQ8ftVBxWQbihvZL1DfzGGWA==", - "dev": true - }, - "math-interval-parser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/math-interval-parser/-/math-interval-parser-2.0.1.tgz", - "integrity": "sha512-VmlAmb0UJwlvMyx8iPhXUDnVW1F9IrGEd9CIOmv+XL8AErCUUuozoDMrgImvnYt2A+53qVX/tPW6YJurMKYsvA==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "messageformat": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/messageformat/-/messageformat-2.3.0.tgz", - "integrity": "sha512-uTzvsv0lTeQxYI2y1NPa1lItL5VRI8Gb93Y2K2ue5gBPyrbJxfDi/EYWxh2PKv5yO42AJeeqblS9MJSh/IEk4w==", - "dev": true, - "requires": { - "make-plural": "^4.3.0", - "messageformat-formatters": "^2.0.1", - "messageformat-parser": "^4.1.2" - }, - "dependencies": { - "make-plural": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz", - "integrity": "sha512-xTYd4JVHpSCW+aqDof6w/MebaMVNTVYBZhbB/vi513xXdiPT92JMVCo0Jq8W2UZnzYRFeVbQiQ+I25l13JuKvA==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - } - } - }, - "messageformat-formatters": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/messageformat-formatters/-/messageformat-formatters-2.0.1.tgz", - "integrity": "sha512-E/lQRXhtHwGuiQjI7qxkLp8AHbMD5r2217XNe/SREbBlSawe0lOqsFb7rflZJmlQFSULNLIqlcjjsCPlB3m3Mg==", - "dev": true - }, - "messageformat-parser": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-4.1.3.tgz", - "integrity": "sha512-2fU3XDCanRqeOCkn7R5zW5VQHWf+T3hH65SzuqRvjatBK7r4uyFa5mEX+k6F9Bd04LVM5G4/BHBTUJsOdW7uyg==", - "dev": true - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "minipass": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", - "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "mocha": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz", - "integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==", - "dev": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.2", - "debug": "4.3.2", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.7", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "nanoid": "3.1.25", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.1.5", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "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-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "mustache": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", - "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", - "dev": true - }, - "nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "dev": true - }, - "nanoid": { - "version": "3.1.25", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", - "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node-fetch": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", - "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", - "dev": true - }, - "nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "dev": true, - "requires": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", - "dev": true - }, - "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "optjs": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", - "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=", - "dev": true - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "promise.prototype.finally": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/promise.prototype.finally/-/promise.prototype.finally-3.1.3.tgz", - "integrity": "sha512-EXRF3fC9/0gz4qkt/f5EP5iW4kj9oFpBICNpCNOb/52+8nlHIX07FPLbi/q4qYBQ1xZqivMzTpNQSnArVASolQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "proto3-json-serializer": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-0.1.4.tgz", - "integrity": "sha512-bFzdsKU/zaTobWrRxRniMZIzzcgKYlmBWL1gAcTXZ2M7TQTGPI0JoYYs6bN7tpWj59ZCfwg7Ii/A2e8BbQGYnQ==", - "dev": true - }, - "protobufjs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", - "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", - "dev": true, - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "retry-request": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.2.2.tgz", - "integrity": "sha512-xA93uxUD/rogV7BV59agW/JHPGXeREMWiZc9jhcwY4YdZ7QOtC7qbomYg0n4wyk2lJhggjvKvhNX8wln/Aldhg==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "extend": "^3.0.2" - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "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 - }, - "source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true - }, - "ts-node": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", - "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "0.7.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "yn": "3.1.1" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - } - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dev": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", - "dev": true - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "workerpool": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", - "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "dependencies": { - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - } - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } - } -} diff --git a/test/prod/package.json b/test/prod/package.json deleted file mode 100644 index f55c007a..00000000 --- a/test/prod/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "lis-mon-livre-test", - "version": "1.0.0", - "description": "", - "private": true, - "scripts": { - "lint": "eslint \"test/*.ts\"", - "enable-activity-controls": "env GOOGLE_APPLICATION_CREDENTIALS=$PWD/service_account.json web-and-app-activity-controls", - "test": "npm run lint && env GOOGLE_APPLICATION_CREDENTIALS=$PWD/service_account.json PROJECT_ID=$(cat $PWD/service_account.json| jq -r '.project_id') mocha --recursive --require ts-node/register test/*.ts" - }, - "author": "", - "license": "ISC", - "devDependencies": { - "@assistant/conversation-testing": "^1.0.0", - "@types/mocha": "^9.0.0", - "@types/node": "^16.11.4", - "@typescript-eslint/eslint-plugin": "^5.2.0", - "@typescript-eslint/parser": "^5.1.0", - "chai": "^4.3.4", - "eslint": "^8.1.0", - "mocha": "^9.1.3", - "ts-node": "^10.4.0", - "typescript": "^4.4.4" - } -} diff --git a/test/prod/test/test1.ts b/test/prod/test/test1.ts deleted file mode 100644 index 775959f1..00000000 --- a/test/prod/test/test1.ts +++ /dev/null @@ -1,56 +0,0 @@ -import 'mocha'; - -import {env} from 'process'; -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; - -const DEFAULT_LOCALE = 'fr-FR'; -const DEFAULT_SURFACE = 'PHONE'; -const CONTINUE_CONVO_PROMPT = "Bienvenue dans l'application d'écoute de livre audio valentin hauy Que voulez-vous faire ? Vous pouvez dire informations ou espace membres"; - -const PROJECT_ID = env['PROJECT_ID'] || ''; -const TRIGGER_PHRASE = 'Parler avec valentin audio'; - -console.log(`PROJECT_ID=${PROJECT_ID}`); - -ok(PROJECT_ID, 'no PROJECT_ID'); - -// tslint:disable:only-arrow-functions - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(CONTINUE_CONVO_PROMPT); - test.assertText(CONTINUE_CONVO_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_lvl1'); - - await test.sendQuery("espace membres"); - test.assertText("Pour continuer d'utiliser valentin audio, je dois associer votre compte valentin audio à Google. Êtes-vous d'accord ?"); - - await test.sendQuery("oui"); - test.assertText(""); - - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('trigger only', async () => { - await startConversation(); - // test.assertConversationEnded(); - }); -}); diff --git a/test/dev/test/constant.ts b/test/test/constant.ts similarity index 100% rename from test/dev/test/constant.ts rename to test/test/constant.ts diff --git a/test/dev/test/test1.ts b/test/test/test1.ts similarity index 100% rename from test/dev/test/test1.ts rename to test/test/test1.ts diff --git a/test/dev/test/test10.ts b/test/test/test10.ts similarity index 100% rename from test/dev/test/test10.ts rename to test/test/test10.ts diff --git a/test/dev/test/test11.ts b/test/test/test11.ts similarity index 100% rename from test/dev/test/test11.ts rename to test/test/test11.ts diff --git a/test/dev/test/test12.ts b/test/test/test12.ts similarity index 100% rename from test/dev/test/test12.ts rename to test/test/test12.ts diff --git a/test/dev/test/test13.ts b/test/test/test13.ts similarity index 100% rename from test/dev/test/test13.ts rename to test/test/test13.ts diff --git a/test/dev/test/test2.ts b/test/test/test2.ts similarity index 100% rename from test/dev/test/test2.ts rename to test/test/test2.ts diff --git a/test/dev/test/test3-2.ts b/test/test/test3-2.ts similarity index 100% rename from test/dev/test/test3-2.ts rename to test/test/test3-2.ts diff --git a/test/dev/test/test3.ts b/test/test/test3.ts similarity index 100% rename from test/dev/test/test3.ts rename to test/test/test3.ts diff --git a/test/dev/test/test4.ts b/test/test/test4.ts similarity index 100% rename from test/dev/test/test4.ts rename to test/test/test4.ts diff --git a/test/dev/test/test5.ts b/test/test/test5.ts similarity index 100% rename from test/dev/test/test5.ts rename to test/test/test5.ts diff --git a/test/dev/test/test6.ts b/test/test/test6.ts similarity index 100% rename from test/dev/test/test6.ts rename to test/test/test6.ts diff --git a/test/dev/test/test7.ts b/test/test/test7.ts similarity index 100% rename from test/dev/test/test7.ts rename to test/test/test7.ts diff --git a/test/dev/test/test8.ts b/test/test/test8.ts similarity index 100% rename from test/dev/test/test8.ts rename to test/test/test8.ts diff --git a/test/dev/test/test9.ts b/test/test/test9.ts similarity index 100% rename from test/dev/test/test9.ts rename to test/test/test9.ts From 4ce58e75f7d687463c670f48cd496b3069d7a6af Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 31 Jan 2022 15:42:39 +0100 Subject: [PATCH 082/180] fix: actions test --- .github/workflows/sdk-test-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sdk-test-dev.yml b/.github/workflows/sdk-test-dev.yml index 5b8491b0..4df5018b 100644 --- a/.github/workflows/sdk-test-dev.yml +++ b/.github/workflows/sdk-test-dev.yml @@ -22,7 +22,7 @@ jobs: # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ defaults: run: - working-directory: './test/dev' + working-directory: './test' steps: From a5344bfca0dcde7e8d54970a597b4f12e037c37c Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 31 Jan 2022 15:51:34 +0100 Subject: [PATCH 083/180] chore avh-dev --- README.md | 8 +- sdk/{test => }/actions/actions.yaml | 0 .../custom/global/actions.intent.CANCEL.yaml | 0 .../custom/global/actions.intent.MAIN.yaml | 0 .../actions.intent.MEDIA_STATUS_STOPPED.yaml | 0 .../global/actions.intent.NO_INPUT_1.yaml | 0 .../global/actions.intent.NO_INPUT_2.yaml | 0 .../global/actions.intent.NO_INPUT_FINAL.yaml | 0 .../global/actions.intent.NO_MATCH_1.yaml | 0 .../global/actions.intent.NO_MATCH_2.yaml | 0 .../global/actions.intent.NO_MATCH_FINAL.yaml | 0 .../intents/enter_member_space_lvl1.yaml | 0 .../intents/get_info_association_lvl1.yaml | 0 .../custom/intents/i_want_to_listen_lvl3.yaml | 0 .../custom/intents/listen_audiobook_lvl1.yaml | 0 .../custom/intents/listen_audiobook_lvl2.yaml | 0 sdk/{test => }/custom/intents/listen_toc.yaml | 0 sdk/{test => }/custom/intents/menu.yaml | 0 sdk/{test => }/custom/intents/next.yaml | 0 sdk/{prod => }/custom/intents/no.yaml | 0 .../custom/intents/remaing_time_player.yaml | 0 sdk/{test => }/custom/intents/repeat.yaml | 0 .../custom/intents/resume_audiobook_lvl2.yaml | 0 .../intents/resume_listening_player.yaml | 0 .../selection_all_publication_lvl3.yaml | 0 .../intents/selection_audiobook_lvl2.yaml | 0 .../custom/intents/selection_genre_lvl3.yaml | 0 .../intents/selection_my_list_lvl3.yaml | 0 .../intents/selection_thematic_list_lvl3.yaml | 0 sdk/{test => }/custom/intents/stop.yaml | 0 .../custom/intents/test_player_sdk.yaml | 0 .../custom/intents/test_setup_sdk.yaml | 0 .../custom/intents/test_webhook.yaml | 0 sdk/{prod => }/custom/intents/yes.yaml | 0 ...sk_to_resume_listening_at_last_offset.yaml | 0 sdk/{test => }/custom/scenes/home_lvl1.yaml | 0 .../scenes/home_lvl1_AccountLinking.yaml | 0 .../custom/scenes/home_members_lvl2.yaml | 0 sdk/{test => }/custom/scenes/player.yaml | 0 sdk/{test => }/custom/scenes/player_toc.yaml | 0 sdk/{test => }/custom/scenes/search.yaml | 0 .../custom/scenes/select_group.yaml | 0 .../custom/scenes/select_publication.yaml | 0 .../custom/scenes/selection_lvl3.yaml | 0 sdk/{prod => }/custom/types/string.yaml | 0 sdk/{prod => }/manifest.yaml | 0 sdk/prod/actions/actions.yaml | 2 - .../custom/global/actions.intent.MAIN.yaml | 9 - .../custom/intents/resume_audiobook_lvl2.yaml | 15 - .../intents/resume_listening_player.yaml | 3 - ...sk_to_resume_listening_at_last_offset.yaml | 11 - sdk/prod/custom/scenes/home_lvl1.yaml | 31 - sdk/prod/custom/scenes/home_members_lvl2.yaml | 25 - sdk/prod/custom/scenes/player.yaml | 21 - sdk/prod/custom/scenes/search.yaml | 21 - .../scenes/select_pub_after_search.yaml | 69 - .../scenes/select_pub_after_selection.yaml | 67 - sdk/prod/custom/scenes/selection_lvl3.yaml | 10 - sdk/prod/settings/settings.yaml | 24 - .../webhooks/ActionsOnGoogleFulfillment.yaml | 22 - sdk/{test => }/settings/settings.yaml | 0 .../custom/global/actions.intent.CANCEL.yaml | 9 - .../global/actions.intent.NO_INPUT_1.yaml | 7 - .../global/actions.intent.NO_INPUT_2.yaml | 7 - .../global/actions.intent.NO_INPUT_FINAL.yaml | 8 - .../global/actions.intent.NO_MATCH_1.yaml | 7 - .../global/actions.intent.NO_MATCH_2.yaml | 7 - .../global/actions.intent.NO_MATCH_FINAL.yaml | 8 - .../intents/enter_member_space_lvl1.yaml | 5 - .../intents/get_info_association_lvl1.yaml | 4 - .../custom/intents/i_want_to_listen_lvl3.yaml | 10 - .../custom/intents/listen_audiobook_lvl1.yaml | 6 - .../custom/intents/listen_audiobook_lvl2.yaml | 12 - sdk/test/custom/intents/no.yaml | 5 - .../custom/intents/remaing_time_player.yaml | 7 - .../intents/selection_audiobook_lvl2.yaml | 5 - .../custom/intents/selection_genre_lvl3.yaml | 4 - .../intents/selection_my_list_lvl3.yaml | 4 - .../intents/selection_thematic_list_lvl3.yaml | 4 - sdk/test/custom/intents/test_webhook.yaml | 3 - sdk/test/custom/intents/yes.yaml | 6 - .../scenes/home_lvl1_AccountLinking.yaml | 19 - sdk/test/custom/types/string.yaml | 1 - sdk/test/manifest.yaml | 1 - .../webhooks/ActionsOnGoogleFulfillment.yaml | 0 test/dev/.eslintrc.json | 20 - test/dev/package-lock.json | 3094 ---------------- test/dev/package.json | 26 - test/dev/test/constant.ts | 18 - test/dev/test/test1.ts | 44 - test/dev/test/test10.ts | 58 - test/dev/test/test11.ts | 58 - test/dev/test/test12.ts | 67 - test/dev/test/test13.ts | 60 - test/dev/test/test2.ts | 57 - test/dev/test/test3-2.ts | 74 - test/dev/test/test3.ts | 63 - test/dev/test/test4.ts | 258 -- test/dev/test/test5.ts | 221 -- test/dev/test/test6.ts | 248 -- test/dev/test/test7.ts | 254 -- test/dev/test/test8.ts | 256 -- test/dev/test/test9.ts | 133 - test/prod/.eslintrc.json | 20 - test/prod/package-lock.json | 3161 ----------------- test/prod/package.json | 25 - test/prod/test/test1.ts | 56 - 107 files changed, 7 insertions(+), 8751 deletions(-) rename sdk/{test => }/actions/actions.yaml (100%) rename sdk/{prod => }/custom/global/actions.intent.CANCEL.yaml (100%) rename sdk/{test => }/custom/global/actions.intent.MAIN.yaml (100%) rename sdk/{test => }/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml (100%) rename sdk/{prod => }/custom/global/actions.intent.NO_INPUT_1.yaml (100%) rename sdk/{prod => }/custom/global/actions.intent.NO_INPUT_2.yaml (100%) rename sdk/{prod => }/custom/global/actions.intent.NO_INPUT_FINAL.yaml (100%) rename sdk/{prod => }/custom/global/actions.intent.NO_MATCH_1.yaml (100%) rename sdk/{prod => }/custom/global/actions.intent.NO_MATCH_2.yaml (100%) rename sdk/{prod => }/custom/global/actions.intent.NO_MATCH_FINAL.yaml (100%) rename sdk/{prod => }/custom/intents/enter_member_space_lvl1.yaml (100%) rename sdk/{prod => }/custom/intents/get_info_association_lvl1.yaml (100%) rename sdk/{prod => }/custom/intents/i_want_to_listen_lvl3.yaml (100%) rename sdk/{prod => }/custom/intents/listen_audiobook_lvl1.yaml (100%) rename sdk/{prod => }/custom/intents/listen_audiobook_lvl2.yaml (100%) rename sdk/{test => }/custom/intents/listen_toc.yaml (100%) rename sdk/{test => }/custom/intents/menu.yaml (100%) rename sdk/{test => }/custom/intents/next.yaml (100%) rename sdk/{prod => }/custom/intents/no.yaml (100%) rename sdk/{prod => }/custom/intents/remaing_time_player.yaml (100%) rename sdk/{test => }/custom/intents/repeat.yaml (100%) rename sdk/{test => }/custom/intents/resume_audiobook_lvl2.yaml (100%) rename sdk/{test => }/custom/intents/resume_listening_player.yaml (100%) rename sdk/{test => }/custom/intents/selection_all_publication_lvl3.yaml (100%) rename sdk/{prod => }/custom/intents/selection_audiobook_lvl2.yaml (100%) rename sdk/{prod => }/custom/intents/selection_genre_lvl3.yaml (100%) rename sdk/{prod => }/custom/intents/selection_my_list_lvl3.yaml (100%) rename sdk/{prod => }/custom/intents/selection_thematic_list_lvl3.yaml (100%) rename sdk/{test => }/custom/intents/stop.yaml (100%) rename sdk/{test => }/custom/intents/test_player_sdk.yaml (100%) rename sdk/{test => }/custom/intents/test_setup_sdk.yaml (100%) rename sdk/{prod => }/custom/intents/test_webhook.yaml (100%) rename sdk/{prod => }/custom/intents/yes.yaml (100%) rename sdk/{test => }/custom/scenes/ask_to_resume_listening_at_last_offset.yaml (100%) rename sdk/{test => }/custom/scenes/home_lvl1.yaml (100%) rename sdk/{prod => }/custom/scenes/home_lvl1_AccountLinking.yaml (100%) rename sdk/{test => }/custom/scenes/home_members_lvl2.yaml (100%) rename sdk/{test => }/custom/scenes/player.yaml (100%) rename sdk/{test => }/custom/scenes/player_toc.yaml (100%) rename sdk/{test => }/custom/scenes/search.yaml (100%) rename sdk/{test => }/custom/scenes/select_group.yaml (100%) rename sdk/{test => }/custom/scenes/select_publication.yaml (100%) rename sdk/{test => }/custom/scenes/selection_lvl3.yaml (100%) rename sdk/{prod => }/custom/types/string.yaml (100%) rename sdk/{prod => }/manifest.yaml (100%) delete mode 100644 sdk/prod/actions/actions.yaml delete mode 100644 sdk/prod/custom/global/actions.intent.MAIN.yaml delete mode 100644 sdk/prod/custom/intents/resume_audiobook_lvl2.yaml delete mode 100644 sdk/prod/custom/intents/resume_listening_player.yaml delete mode 100644 sdk/prod/custom/scenes/ask_to_resume_listening_at_last_offset.yaml delete mode 100644 sdk/prod/custom/scenes/home_lvl1.yaml delete mode 100644 sdk/prod/custom/scenes/home_members_lvl2.yaml delete mode 100644 sdk/prod/custom/scenes/player.yaml delete mode 100644 sdk/prod/custom/scenes/search.yaml delete mode 100644 sdk/prod/custom/scenes/select_pub_after_search.yaml delete mode 100644 sdk/prod/custom/scenes/select_pub_after_selection.yaml delete mode 100644 sdk/prod/custom/scenes/selection_lvl3.yaml delete mode 100644 sdk/prod/settings/settings.yaml delete mode 100644 sdk/prod/webhooks/ActionsOnGoogleFulfillment.yaml rename sdk/{test => }/settings/settings.yaml (100%) delete mode 100644 sdk/test/custom/global/actions.intent.CANCEL.yaml delete mode 100644 sdk/test/custom/global/actions.intent.NO_INPUT_1.yaml delete mode 100644 sdk/test/custom/global/actions.intent.NO_INPUT_2.yaml delete mode 100644 sdk/test/custom/global/actions.intent.NO_INPUT_FINAL.yaml delete mode 100644 sdk/test/custom/global/actions.intent.NO_MATCH_1.yaml delete mode 100644 sdk/test/custom/global/actions.intent.NO_MATCH_2.yaml delete mode 100644 sdk/test/custom/global/actions.intent.NO_MATCH_FINAL.yaml delete mode 100644 sdk/test/custom/intents/enter_member_space_lvl1.yaml delete mode 100644 sdk/test/custom/intents/get_info_association_lvl1.yaml delete mode 100644 sdk/test/custom/intents/i_want_to_listen_lvl3.yaml delete mode 100644 sdk/test/custom/intents/listen_audiobook_lvl1.yaml delete mode 100644 sdk/test/custom/intents/listen_audiobook_lvl2.yaml delete mode 100644 sdk/test/custom/intents/no.yaml delete mode 100644 sdk/test/custom/intents/remaing_time_player.yaml delete mode 100644 sdk/test/custom/intents/selection_audiobook_lvl2.yaml delete mode 100644 sdk/test/custom/intents/selection_genre_lvl3.yaml delete mode 100644 sdk/test/custom/intents/selection_my_list_lvl3.yaml delete mode 100644 sdk/test/custom/intents/selection_thematic_list_lvl3.yaml delete mode 100644 sdk/test/custom/intents/test_webhook.yaml delete mode 100644 sdk/test/custom/intents/yes.yaml delete mode 100644 sdk/test/custom/scenes/home_lvl1_AccountLinking.yaml delete mode 100644 sdk/test/custom/types/string.yaml delete mode 100644 sdk/test/manifest.yaml rename sdk/{test => }/webhooks/ActionsOnGoogleFulfillment.yaml (100%) delete mode 100644 test/dev/.eslintrc.json delete mode 100644 test/dev/package-lock.json delete mode 100644 test/dev/package.json delete mode 100644 test/dev/test/constant.ts delete mode 100644 test/dev/test/test1.ts delete mode 100644 test/dev/test/test10.ts delete mode 100644 test/dev/test/test11.ts delete mode 100644 test/dev/test/test12.ts delete mode 100644 test/dev/test/test13.ts delete mode 100644 test/dev/test/test2.ts delete mode 100644 test/dev/test/test3-2.ts delete mode 100644 test/dev/test/test3.ts delete mode 100644 test/dev/test/test4.ts delete mode 100644 test/dev/test/test5.ts delete mode 100644 test/dev/test/test6.ts delete mode 100644 test/dev/test/test7.ts delete mode 100644 test/dev/test/test8.ts delete mode 100644 test/dev/test/test9.ts delete mode 100644 test/prod/.eslintrc.json delete mode 100644 test/prod/package-lock.json delete mode 100644 test/prod/package.json delete mode 100644 test/prod/test/test1.ts diff --git a/README.md b/README.md index fdf849b3..d0a8f96a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,13 @@ # lis-mon-livre +> avh-dev - valentin-5 + +- https://console.firebase.google.com/u/1/project/valentin-5/firestore/data +- https://console.actions.google.com/u/1/project/valentin-5/overview +- https://console.cloud.google.com/logs/query?referrer=search&authuser=1&project=valentin-5 + ## gactions -`cd sdk && gactions pull --force --clean --project-id valentin-4` +`cd sdk && gactions pull --force --clean --project-id valentin-5` diff --git a/sdk/test/actions/actions.yaml b/sdk/actions/actions.yaml similarity index 100% rename from sdk/test/actions/actions.yaml rename to sdk/actions/actions.yaml diff --git a/sdk/prod/custom/global/actions.intent.CANCEL.yaml b/sdk/custom/global/actions.intent.CANCEL.yaml similarity index 100% rename from sdk/prod/custom/global/actions.intent.CANCEL.yaml rename to sdk/custom/global/actions.intent.CANCEL.yaml diff --git a/sdk/test/custom/global/actions.intent.MAIN.yaml b/sdk/custom/global/actions.intent.MAIN.yaml similarity index 100% rename from sdk/test/custom/global/actions.intent.MAIN.yaml rename to sdk/custom/global/actions.intent.MAIN.yaml diff --git a/sdk/test/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml b/sdk/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml similarity index 100% rename from sdk/test/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml rename to sdk/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml diff --git a/sdk/prod/custom/global/actions.intent.NO_INPUT_1.yaml b/sdk/custom/global/actions.intent.NO_INPUT_1.yaml similarity index 100% rename from sdk/prod/custom/global/actions.intent.NO_INPUT_1.yaml rename to sdk/custom/global/actions.intent.NO_INPUT_1.yaml diff --git a/sdk/prod/custom/global/actions.intent.NO_INPUT_2.yaml b/sdk/custom/global/actions.intent.NO_INPUT_2.yaml similarity index 100% rename from sdk/prod/custom/global/actions.intent.NO_INPUT_2.yaml rename to sdk/custom/global/actions.intent.NO_INPUT_2.yaml diff --git a/sdk/prod/custom/global/actions.intent.NO_INPUT_FINAL.yaml b/sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml similarity index 100% rename from sdk/prod/custom/global/actions.intent.NO_INPUT_FINAL.yaml rename to sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml diff --git a/sdk/prod/custom/global/actions.intent.NO_MATCH_1.yaml b/sdk/custom/global/actions.intent.NO_MATCH_1.yaml similarity index 100% rename from sdk/prod/custom/global/actions.intent.NO_MATCH_1.yaml rename to sdk/custom/global/actions.intent.NO_MATCH_1.yaml diff --git a/sdk/prod/custom/global/actions.intent.NO_MATCH_2.yaml b/sdk/custom/global/actions.intent.NO_MATCH_2.yaml similarity index 100% rename from sdk/prod/custom/global/actions.intent.NO_MATCH_2.yaml rename to sdk/custom/global/actions.intent.NO_MATCH_2.yaml diff --git a/sdk/prod/custom/global/actions.intent.NO_MATCH_FINAL.yaml b/sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml similarity index 100% rename from sdk/prod/custom/global/actions.intent.NO_MATCH_FINAL.yaml rename to sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml diff --git a/sdk/prod/custom/intents/enter_member_space_lvl1.yaml b/sdk/custom/intents/enter_member_space_lvl1.yaml similarity index 100% rename from sdk/prod/custom/intents/enter_member_space_lvl1.yaml rename to sdk/custom/intents/enter_member_space_lvl1.yaml diff --git a/sdk/prod/custom/intents/get_info_association_lvl1.yaml b/sdk/custom/intents/get_info_association_lvl1.yaml similarity index 100% rename from sdk/prod/custom/intents/get_info_association_lvl1.yaml rename to sdk/custom/intents/get_info_association_lvl1.yaml diff --git a/sdk/prod/custom/intents/i_want_to_listen_lvl3.yaml b/sdk/custom/intents/i_want_to_listen_lvl3.yaml similarity index 100% rename from sdk/prod/custom/intents/i_want_to_listen_lvl3.yaml rename to sdk/custom/intents/i_want_to_listen_lvl3.yaml diff --git a/sdk/prod/custom/intents/listen_audiobook_lvl1.yaml b/sdk/custom/intents/listen_audiobook_lvl1.yaml similarity index 100% rename from sdk/prod/custom/intents/listen_audiobook_lvl1.yaml rename to sdk/custom/intents/listen_audiobook_lvl1.yaml diff --git a/sdk/prod/custom/intents/listen_audiobook_lvl2.yaml b/sdk/custom/intents/listen_audiobook_lvl2.yaml similarity index 100% rename from sdk/prod/custom/intents/listen_audiobook_lvl2.yaml rename to sdk/custom/intents/listen_audiobook_lvl2.yaml diff --git a/sdk/test/custom/intents/listen_toc.yaml b/sdk/custom/intents/listen_toc.yaml similarity index 100% rename from sdk/test/custom/intents/listen_toc.yaml rename to sdk/custom/intents/listen_toc.yaml diff --git a/sdk/test/custom/intents/menu.yaml b/sdk/custom/intents/menu.yaml similarity index 100% rename from sdk/test/custom/intents/menu.yaml rename to sdk/custom/intents/menu.yaml diff --git a/sdk/test/custom/intents/next.yaml b/sdk/custom/intents/next.yaml similarity index 100% rename from sdk/test/custom/intents/next.yaml rename to sdk/custom/intents/next.yaml diff --git a/sdk/prod/custom/intents/no.yaml b/sdk/custom/intents/no.yaml similarity index 100% rename from sdk/prod/custom/intents/no.yaml rename to sdk/custom/intents/no.yaml diff --git a/sdk/prod/custom/intents/remaing_time_player.yaml b/sdk/custom/intents/remaing_time_player.yaml similarity index 100% rename from sdk/prod/custom/intents/remaing_time_player.yaml rename to sdk/custom/intents/remaing_time_player.yaml diff --git a/sdk/test/custom/intents/repeat.yaml b/sdk/custom/intents/repeat.yaml similarity index 100% rename from sdk/test/custom/intents/repeat.yaml rename to sdk/custom/intents/repeat.yaml diff --git a/sdk/test/custom/intents/resume_audiobook_lvl2.yaml b/sdk/custom/intents/resume_audiobook_lvl2.yaml similarity index 100% rename from sdk/test/custom/intents/resume_audiobook_lvl2.yaml rename to sdk/custom/intents/resume_audiobook_lvl2.yaml diff --git a/sdk/test/custom/intents/resume_listening_player.yaml b/sdk/custom/intents/resume_listening_player.yaml similarity index 100% rename from sdk/test/custom/intents/resume_listening_player.yaml rename to sdk/custom/intents/resume_listening_player.yaml diff --git a/sdk/test/custom/intents/selection_all_publication_lvl3.yaml b/sdk/custom/intents/selection_all_publication_lvl3.yaml similarity index 100% rename from sdk/test/custom/intents/selection_all_publication_lvl3.yaml rename to sdk/custom/intents/selection_all_publication_lvl3.yaml diff --git a/sdk/prod/custom/intents/selection_audiobook_lvl2.yaml b/sdk/custom/intents/selection_audiobook_lvl2.yaml similarity index 100% rename from sdk/prod/custom/intents/selection_audiobook_lvl2.yaml rename to sdk/custom/intents/selection_audiobook_lvl2.yaml diff --git a/sdk/prod/custom/intents/selection_genre_lvl3.yaml b/sdk/custom/intents/selection_genre_lvl3.yaml similarity index 100% rename from sdk/prod/custom/intents/selection_genre_lvl3.yaml rename to sdk/custom/intents/selection_genre_lvl3.yaml diff --git a/sdk/prod/custom/intents/selection_my_list_lvl3.yaml b/sdk/custom/intents/selection_my_list_lvl3.yaml similarity index 100% rename from sdk/prod/custom/intents/selection_my_list_lvl3.yaml rename to sdk/custom/intents/selection_my_list_lvl3.yaml diff --git a/sdk/prod/custom/intents/selection_thematic_list_lvl3.yaml b/sdk/custom/intents/selection_thematic_list_lvl3.yaml similarity index 100% rename from sdk/prod/custom/intents/selection_thematic_list_lvl3.yaml rename to sdk/custom/intents/selection_thematic_list_lvl3.yaml diff --git a/sdk/test/custom/intents/stop.yaml b/sdk/custom/intents/stop.yaml similarity index 100% rename from sdk/test/custom/intents/stop.yaml rename to sdk/custom/intents/stop.yaml diff --git a/sdk/test/custom/intents/test_player_sdk.yaml b/sdk/custom/intents/test_player_sdk.yaml similarity index 100% rename from sdk/test/custom/intents/test_player_sdk.yaml rename to sdk/custom/intents/test_player_sdk.yaml diff --git a/sdk/test/custom/intents/test_setup_sdk.yaml b/sdk/custom/intents/test_setup_sdk.yaml similarity index 100% rename from sdk/test/custom/intents/test_setup_sdk.yaml rename to sdk/custom/intents/test_setup_sdk.yaml diff --git a/sdk/prod/custom/intents/test_webhook.yaml b/sdk/custom/intents/test_webhook.yaml similarity index 100% rename from sdk/prod/custom/intents/test_webhook.yaml rename to sdk/custom/intents/test_webhook.yaml diff --git a/sdk/prod/custom/intents/yes.yaml b/sdk/custom/intents/yes.yaml similarity index 100% rename from sdk/prod/custom/intents/yes.yaml rename to sdk/custom/intents/yes.yaml diff --git a/sdk/test/custom/scenes/ask_to_resume_listening_at_last_offset.yaml b/sdk/custom/scenes/ask_to_resume_listening_at_last_offset.yaml similarity index 100% rename from sdk/test/custom/scenes/ask_to_resume_listening_at_last_offset.yaml rename to sdk/custom/scenes/ask_to_resume_listening_at_last_offset.yaml diff --git a/sdk/test/custom/scenes/home_lvl1.yaml b/sdk/custom/scenes/home_lvl1.yaml similarity index 100% rename from sdk/test/custom/scenes/home_lvl1.yaml rename to sdk/custom/scenes/home_lvl1.yaml diff --git a/sdk/prod/custom/scenes/home_lvl1_AccountLinking.yaml b/sdk/custom/scenes/home_lvl1_AccountLinking.yaml similarity index 100% rename from sdk/prod/custom/scenes/home_lvl1_AccountLinking.yaml rename to sdk/custom/scenes/home_lvl1_AccountLinking.yaml diff --git a/sdk/test/custom/scenes/home_members_lvl2.yaml b/sdk/custom/scenes/home_members_lvl2.yaml similarity index 100% rename from sdk/test/custom/scenes/home_members_lvl2.yaml rename to sdk/custom/scenes/home_members_lvl2.yaml diff --git a/sdk/test/custom/scenes/player.yaml b/sdk/custom/scenes/player.yaml similarity index 100% rename from sdk/test/custom/scenes/player.yaml rename to sdk/custom/scenes/player.yaml diff --git a/sdk/test/custom/scenes/player_toc.yaml b/sdk/custom/scenes/player_toc.yaml similarity index 100% rename from sdk/test/custom/scenes/player_toc.yaml rename to sdk/custom/scenes/player_toc.yaml diff --git a/sdk/test/custom/scenes/search.yaml b/sdk/custom/scenes/search.yaml similarity index 100% rename from sdk/test/custom/scenes/search.yaml rename to sdk/custom/scenes/search.yaml diff --git a/sdk/test/custom/scenes/select_group.yaml b/sdk/custom/scenes/select_group.yaml similarity index 100% rename from sdk/test/custom/scenes/select_group.yaml rename to sdk/custom/scenes/select_group.yaml diff --git a/sdk/test/custom/scenes/select_publication.yaml b/sdk/custom/scenes/select_publication.yaml similarity index 100% rename from sdk/test/custom/scenes/select_publication.yaml rename to sdk/custom/scenes/select_publication.yaml diff --git a/sdk/test/custom/scenes/selection_lvl3.yaml b/sdk/custom/scenes/selection_lvl3.yaml similarity index 100% rename from sdk/test/custom/scenes/selection_lvl3.yaml rename to sdk/custom/scenes/selection_lvl3.yaml diff --git a/sdk/prod/custom/types/string.yaml b/sdk/custom/types/string.yaml similarity index 100% rename from sdk/prod/custom/types/string.yaml rename to sdk/custom/types/string.yaml diff --git a/sdk/prod/manifest.yaml b/sdk/manifest.yaml similarity index 100% rename from sdk/prod/manifest.yaml rename to sdk/manifest.yaml diff --git a/sdk/prod/actions/actions.yaml b/sdk/prod/actions/actions.yaml deleted file mode 100644 index f82f9c46..00000000 --- a/sdk/prod/actions/actions.yaml +++ /dev/null @@ -1,2 +0,0 @@ -custom: - actions.intent.MAIN: {} diff --git a/sdk/prod/custom/global/actions.intent.MAIN.yaml b/sdk/prod/custom/global/actions.intent.MAIN.yaml deleted file mode 100644 index 463025af..00000000 --- a/sdk/prod/custom/global/actions.intent.MAIN.yaml +++ /dev/null @@ -1,9 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Bienvenue dans l'application d'écoute de livre audio valentin - hauy -transitionToScene: home_lvl1 diff --git a/sdk/prod/custom/intents/resume_audiobook_lvl2.yaml b/sdk/prod/custom/intents/resume_audiobook_lvl2.yaml deleted file mode 100644 index aab5315b..00000000 --- a/sdk/prod/custom/intents/resume_audiobook_lvl2.yaml +++ /dev/null @@ -1,15 +0,0 @@ -parameters: -- name: number1 - type: - name: actions.type.Number -trainingPhrases: -- lecture d'($number1 'un' auto=true) livre -- lecture de mon livre -- lecture -- lis ($number1 'un' auto=true) livre -- lis mon livre -- reprend la lecture de mon dernier livre -- reprendre l'écoute -- reprendre la lecture de mon dernier livre -- reprend la lecture -- reprendre la lecture diff --git a/sdk/prod/custom/intents/resume_listening_player.yaml b/sdk/prod/custom/intents/resume_listening_player.yaml deleted file mode 100644 index 2cd0b674..00000000 --- a/sdk/prod/custom/intents/resume_listening_player.yaml +++ /dev/null @@ -1,3 +0,0 @@ -trainingPhrases: -- reprend la lecture -- reprendre la lecture diff --git a/sdk/prod/custom/scenes/ask_to_resume_listening_at_last_offset.yaml b/sdk/prod/custom/scenes/ask_to_resume_listening_at_last_offset.yaml deleted file mode 100644 index c575375b..00000000 --- a/sdk/prod/custom/scenes/ask_to_resume_listening_at_last_offset.yaml +++ /dev/null @@ -1,11 +0,0 @@ -intentEvents: -- handler: - webhookHandler: ask_to_resume_listening_at_last_offset__yes - intent: "yes" - transitionToScene: player -- handler: - webhookHandler: ask_to_resume_listening_at_last_offset__no - intent: "no" - transitionToScene: player -onEnter: - webhookHandler: ask_to_resume_listening_at_last_offset diff --git a/sdk/prod/custom/scenes/home_lvl1.yaml b/sdk/prod/custom/scenes/home_lvl1.yaml deleted file mode 100644 index 4bf88a05..00000000 --- a/sdk/prod/custom/scenes/home_lvl1.yaml +++ /dev/null @@ -1,31 +0,0 @@ -intentEvents: -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Voici les informations sur l'association - intent: get_info_association_lvl1 - transitionToScene: home_lvl1 -- intent: enter_member_space_lvl1 - transitionToScene: home_lvl1_AccountLinking -- intent: resume_listening_player - transitionToScene: home_lvl1 -- intent: listen_audiobook_lvl1 - transitionToScene: home_lvl1_AccountLinking -- handler: - webhookHandler: test_webhook - intent: test_webhook - transitionToScene: home_lvl1 -onEnter: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Que voulez-vous faire ? Vous pouvez dire informations ou espace - membres - suggestions: - - title: informations - - title: espace membres diff --git a/sdk/prod/custom/scenes/home_members_lvl2.yaml b/sdk/prod/custom/scenes/home_members_lvl2.yaml deleted file mode 100644 index 2498e69c..00000000 --- a/sdk/prod/custom/scenes/home_members_lvl2.yaml +++ /dev/null @@ -1,25 +0,0 @@ -intentEvents: -- handler: - webhookHandler: ecouter_livre_audio_lvl2 - intent: listen_audiobook_lvl2 - transitionToScene: search -- handler: - webhookHandler: reprendre_mon_livre_lvl2 - intent: resume_audiobook_lvl2 - transitionToScene: ask_to_resume_listening_at_last_offset -- handler: - webhookHandler: selection_livre_lvl2 - intent: selection_audiobook_lvl2 - transitionToScene: selection_lvl3 -onEnter: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Bienvenue dans l'espace membres. Les commandes possibles sont, - sélection, lecture, recherche. Que voulez-vous faire ? - suggestions: - - title: selection d'un livre - - title: lecture du dernier livre - - title: recherche d'un livre diff --git a/sdk/prod/custom/scenes/player.yaml b/sdk/prod/custom/scenes/player.yaml deleted file mode 100644 index 06957f78..00000000 --- a/sdk/prod/custom/scenes/player.yaml +++ /dev/null @@ -1,21 +0,0 @@ -intentEvents: -- handler: - webhookHandler: reprendre_la_lecture - intent: resume_listening_player -- handler: - webhookHandler: remaining_time - intent: remaing_time_player -- handler: - webhookHandler: media_status - intent: actions.intent.MEDIA_STATUS_FINISHED -- handler: - webhookHandler: media_status - intent: actions.intent.MEDIA_STATUS_PAUSED -- handler: - webhookHandler: media_status - intent: actions.intent.MEDIA_STATUS_STOPPED -- handler: - webhookHandler: media_status - intent: actions.intent.MEDIA_STATUS_FAILED -onEnter: - webhookHandler: player diff --git a/sdk/prod/custom/scenes/search.yaml b/sdk/prod/custom/scenes/search.yaml deleted file mode 100644 index 4d95c236..00000000 --- a/sdk/prod/custom/scenes/search.yaml +++ /dev/null @@ -1,21 +0,0 @@ -conditionalEvents: -- condition: scene.slots.status == "FINAL" - handler: - webhookHandler: search_livre_lvl2 -intentEvents: -- intent: resume_listening_player - transitionToScene: search -onEnter: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Que voulez-vous écouter ? Par exemple Zola -slots: -- commitBehavior: - writeSessionParam: query - name: query - required: true - type: - name: string diff --git a/sdk/prod/custom/scenes/select_pub_after_search.yaml b/sdk/prod/custom/scenes/select_pub_after_search.yaml deleted file mode 100644 index f6dc9f7b..00000000 --- a/sdk/prod/custom/scenes/select_pub_after_search.yaml +++ /dev/null @@ -1,69 +0,0 @@ -intentEvents: -- intent: resume_listening_player - transitionToScene: select_pub_after_search -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, merci de le répêter - intent: actions.intent.NO_MATCH_1 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, dite un numéro - intent: actions.intent.NO_MATCH_2 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro. - intent: actions.intent.NO_MATCH_FINAL - transitionToScene: search -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, merci de le répêter - intent: actions.intent.NO_INPUT_1 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, merci de le répêter - intent: actions.intent.NO_INPUT_2 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro - intent: actions.intent.NO_INPUT_FINAL - transitionToScene: search -onEnter: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Pour choisir une publication dite son numéro -onSlotUpdated: - webhookHandler: select_publication_number_after_search -slots: -- commitBehavior: - writeSessionParam: number - name: number - required: true - type: - name: actions.type.Number diff --git a/sdk/prod/custom/scenes/select_pub_after_selection.yaml b/sdk/prod/custom/scenes/select_pub_after_selection.yaml deleted file mode 100644 index 10d12712..00000000 --- a/sdk/prod/custom/scenes/select_pub_after_selection.yaml +++ /dev/null @@ -1,67 +0,0 @@ -intentEvents: -- intent: resume_listening_player - transitionToScene: select_pub_after_selection -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, merci de le répêter - intent: actions.intent.NO_MATCH_1 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, dite un numéro - intent: actions.intent.NO_MATCH_2 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, dite un numéro - intent: actions.intent.NO_MATCH_FINAL -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, dite un numéro - intent: actions.intent.NO_INPUT_1 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, dite un numéro - intent: actions.intent.NO_INPUT_2 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro - intent: actions.intent.NO_INPUT_FINAL -onEnter: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Pour choisir une publication dite son numéro -onSlotUpdated: - webhookHandler: select_publication_number_after_selection -slots: -- commitBehavior: - writeSessionParam: number - name: number - required: true - type: - name: actions.type.Number diff --git a/sdk/prod/custom/scenes/selection_lvl3.yaml b/sdk/prod/custom/scenes/selection_lvl3.yaml deleted file mode 100644 index 583e652a..00000000 --- a/sdk/prod/custom/scenes/selection_lvl3.yaml +++ /dev/null @@ -1,10 +0,0 @@ -intentEvents: -- handler: - webhookHandler: selection_genre_lvl3 - intent: selection_genre_lvl3 -- handler: - webhookHandler: selection_thematic_list_lvl3 - intent: selection_thematic_list_lvl3 -- handler: - webhookHandler: selection_my_list_lvl3 - intent: selection_my_list_lvl3 diff --git a/sdk/prod/settings/settings.yaml b/sdk/prod/settings/settings.yaml deleted file mode 100644 index 3e43f2a0..00000000 --- a/sdk/prod/settings/settings.yaml +++ /dev/null @@ -1,24 +0,0 @@ -accountLinking: - appClientId: "1232456" - authGrantType: IMPLICIT - authorizationUrl: https://opds-auth-test-server-aplqpqv3wa-ey.a.run.app/implicit/login?lang=fr - linkingType: OAUTH -category: EDUCATION_AND_REFERENCE -defaultLocale: fr -localizedSettings: - developerEmail: dev.edrlab@gmail.com - developerName: edrlab - displayName: valentin audio - fullDescription: lis mon live edrlab demo - privacyPolicyUrl: https://www.edrlab.org/lml-privacy-policy/ - pronunciation: valentin audio - sampleInvocations: - - Parler avec valentin audio - - Connecter avec valentin audio - - Discuter avec valentin audio - shortDescription: lis mon livre - smallLogoImage: https://lh3.googleusercontent.com/IPE84cRJZSbgpkLCNMhJFkP_sbh5e18cYRvn30hVHE6nYNLfQ_9a-opqTKbQNThVPUzo8sfP1_cR - voice: female_1 -projectId: valentin-4 -testingInstructions: "login: \n\nadmin\nadmin\n\nyou can test with the query \"zola\" - or \"la guerre des boutons\"" diff --git a/sdk/prod/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/prod/webhooks/ActionsOnGoogleFulfillment.yaml deleted file mode 100644 index 814e3d4d..00000000 --- a/sdk/prod/webhooks/ActionsOnGoogleFulfillment.yaml +++ /dev/null @@ -1,22 +0,0 @@ -handlers: -- name: cancel -- name: ecouter_livre_audio_lvl2 -- name: reprendre_mon_livre_lvl2 -- name: media_status -- name: player -- name: reprendre_la_lecture -- name: remaining_time -- name: selection_livre_lvl2 -- name: select_publication_number_after_search -- name: select_publication_number_after_selection -- name: test_webhook -- name: search_livre_lvl2 -- name: ask_to_resume_listening_at_last_offset -- name: ask_to_resume_listening_at_last_offset__yes -- name: ask_to_resume_listening_at_last_offset__no -- name: selection_genre_lvl3 -- name: selection_thematic_list_lvl3 -- name: selection_my_list_lvl3 -httpsEndpoint: - baseUrl: https://us-central1-valentin-4.cloudfunctions.net/ActionsOnGoogleFulfillment - endpointApiVersion: 2 diff --git a/sdk/test/settings/settings.yaml b/sdk/settings/settings.yaml similarity index 100% rename from sdk/test/settings/settings.yaml rename to sdk/settings/settings.yaml diff --git a/sdk/test/custom/global/actions.intent.CANCEL.yaml b/sdk/test/custom/global/actions.intent.CANCEL.yaml deleted file mode 100644 index 22c095fb..00000000 --- a/sdk/test/custom/global/actions.intent.CANCEL.yaml +++ /dev/null @@ -1,9 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Au revoir et a bientôt - webhookHandler: cancel -transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/test/custom/global/actions.intent.NO_INPUT_1.yaml b/sdk/test/custom/global/actions.intent.NO_INPUT_1.yaml deleted file mode 100644 index de975f82..00000000 --- a/sdk/test/custom/global/actions.intent.NO_INPUT_1.yaml +++ /dev/null @@ -1,7 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n'ai pas entendu. Que voulez-vous dire ? diff --git a/sdk/test/custom/global/actions.intent.NO_INPUT_2.yaml b/sdk/test/custom/global/actions.intent.NO_INPUT_2.yaml deleted file mode 100644 index 59e57245..00000000 --- a/sdk/test/custom/global/actions.intent.NO_INPUT_2.yaml +++ /dev/null @@ -1,7 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Que dite-vous ? diff --git a/sdk/test/custom/global/actions.intent.NO_INPUT_FINAL.yaml b/sdk/test/custom/global/actions.intent.NO_INPUT_FINAL.yaml deleted file mode 100644 index 63087279..00000000 --- a/sdk/test/custom/global/actions.intent.NO_INPUT_FINAL.yaml +++ /dev/null @@ -1,8 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Je quitte l'application -transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/test/custom/global/actions.intent.NO_MATCH_1.yaml b/sdk/test/custom/global/actions.intent.NO_MATCH_1.yaml deleted file mode 100644 index 166efc70..00000000 --- a/sdk/test/custom/global/actions.intent.NO_MATCH_1.yaml +++ /dev/null @@ -1,7 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n'ai pas compris. Que voulez-vous dire ? diff --git a/sdk/test/custom/global/actions.intent.NO_MATCH_2.yaml b/sdk/test/custom/global/actions.intent.NO_MATCH_2.yaml deleted file mode 100644 index deda0dc7..00000000 --- a/sdk/test/custom/global/actions.intent.NO_MATCH_2.yaml +++ /dev/null @@ -1,7 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n'ai vraiment pas compris. Que voulez-vous dire ? diff --git a/sdk/test/custom/global/actions.intent.NO_MATCH_FINAL.yaml b/sdk/test/custom/global/actions.intent.NO_MATCH_FINAL.yaml deleted file mode 100644 index 2f8cf92a..00000000 --- a/sdk/test/custom/global/actions.intent.NO_MATCH_FINAL.yaml +++ /dev/null @@ -1,8 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: malheureusement je m'en vais, je ne comprend pas -transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/test/custom/intents/enter_member_space_lvl1.yaml b/sdk/test/custom/intents/enter_member_space_lvl1.yaml deleted file mode 100644 index b61cfd70..00000000 --- a/sdk/test/custom/intents/enter_member_space_lvl1.yaml +++ /dev/null @@ -1,5 +0,0 @@ -trainingPhrases: -- espace maman -- membres -- espace membres -- Je veux entrer dans l'espace membres diff --git a/sdk/test/custom/intents/get_info_association_lvl1.yaml b/sdk/test/custom/intents/get_info_association_lvl1.yaml deleted file mode 100644 index 837e0830..00000000 --- a/sdk/test/custom/intents/get_info_association_lvl1.yaml +++ /dev/null @@ -1,4 +0,0 @@ -trainingPhrases: -- informations -- obtenir des informations -- Je veux obtenir des informations sur l'association diff --git a/sdk/test/custom/intents/i_want_to_listen_lvl3.yaml b/sdk/test/custom/intents/i_want_to_listen_lvl3.yaml deleted file mode 100644 index aa4c1c81..00000000 --- a/sdk/test/custom/intents/i_want_to_listen_lvl3.yaml +++ /dev/null @@ -1,10 +0,0 @@ -parameters: -- name: query - type: - name: string -trainingPhrases: -- ($query 'le nom du livre suivi de l\'auteur' auto=false) -- je veux écouter ($query 'cyrano de Bergerac d\'Edmond Rostand' auto=false) -- je veux écouter ($query 'le rouge et le noir de stendhall' auto=false) -- je veux écouter ($query 'le rouge et le noir' auto=false) -- je veux écouter ($query 'la chartreuse de parme' auto=false) diff --git a/sdk/test/custom/intents/listen_audiobook_lvl1.yaml b/sdk/test/custom/intents/listen_audiobook_lvl1.yaml deleted file mode 100644 index 5ee4919f..00000000 --- a/sdk/test/custom/intents/listen_audiobook_lvl1.yaml +++ /dev/null @@ -1,6 +0,0 @@ -trainingPhrases: -- recherche d'un livre -- recherche -- rechercher ($number1 'un' auto=true) livre -- écouter un livre -- je veux écouter un livre diff --git a/sdk/test/custom/intents/listen_audiobook_lvl2.yaml b/sdk/test/custom/intents/listen_audiobook_lvl2.yaml deleted file mode 100644 index 61fb43ec..00000000 --- a/sdk/test/custom/intents/listen_audiobook_lvl2.yaml +++ /dev/null @@ -1,12 +0,0 @@ -trainingPhrases: -- recherche d'un livre -- recherche -- rechercher ($number1 'un' auto=true) livre -- je veux écouter -- je veux écouter un livre -- écouter -- livre audio -- livre -- écouter u($number1 'n ' auto=true)audiobook -- écouter un livre -- écouter un livre audio diff --git a/sdk/test/custom/intents/no.yaml b/sdk/test/custom/intents/no.yaml deleted file mode 100644 index 873ac739..00000000 --- a/sdk/test/custom/intents/no.yaml +++ /dev/null @@ -1,5 +0,0 @@ -trainingPhrases: -- "n" -- non -- "no" -- nop diff --git a/sdk/test/custom/intents/remaing_time_player.yaml b/sdk/test/custom/intents/remaing_time_player.yaml deleted file mode 100644 index 703f8de9..00000000 --- a/sdk/test/custom/intents/remaing_time_player.yaml +++ /dev/null @@ -1,7 +0,0 @@ -trainingPhrases: -- combien de temps de lecture me restent-t-il ? -- depuis combien de temps j'écoute ce livre ? -- dis-moi le temps de lecture -- donne moi le temps de lecture -- quel temps me reste-t-il ? -- combien de temps de lecture reste-t-il ? diff --git a/sdk/test/custom/intents/selection_audiobook_lvl2.yaml b/sdk/test/custom/intents/selection_audiobook_lvl2.yaml deleted file mode 100644 index f07b780e..00000000 --- a/sdk/test/custom/intents/selection_audiobook_lvl2.yaml +++ /dev/null @@ -1,5 +0,0 @@ -trainingPhrases: -- ma liste de lecture -- liste de lecture -- selection d'($number1 'un' auto=true) livre -- selection diff --git a/sdk/test/custom/intents/selection_genre_lvl3.yaml b/sdk/test/custom/intents/selection_genre_lvl3.yaml deleted file mode 100644 index 63195424..00000000 --- a/sdk/test/custom/intents/selection_genre_lvl3.yaml +++ /dev/null @@ -1,4 +0,0 @@ -trainingPhrases: -- je veux la sélection par genre -- genre -- sélection par genre diff --git a/sdk/test/custom/intents/selection_my_list_lvl3.yaml b/sdk/test/custom/intents/selection_my_list_lvl3.yaml deleted file mode 100644 index 020db8d6..00000000 --- a/sdk/test/custom/intents/selection_my_list_lvl3.yaml +++ /dev/null @@ -1,4 +0,0 @@ -trainingPhrases: -- je veux ma liste -- ma liste de lecture -- ma liste diff --git a/sdk/test/custom/intents/selection_thematic_list_lvl3.yaml b/sdk/test/custom/intents/selection_thematic_list_lvl3.yaml deleted file mode 100644 index 5ff3b4b0..00000000 --- a/sdk/test/custom/intents/selection_thematic_list_lvl3.yaml +++ /dev/null @@ -1,4 +0,0 @@ -trainingPhrases: -- sélection thématique -- je veux la liste thématique -- liste thématique diff --git a/sdk/test/custom/intents/test_webhook.yaml b/sdk/test/custom/intents/test_webhook.yaml deleted file mode 100644 index b955a43c..00000000 --- a/sdk/test/custom/intents/test_webhook.yaml +++ /dev/null @@ -1,3 +0,0 @@ -trainingPhrases: -- test -- test webhook diff --git a/sdk/test/custom/intents/yes.yaml b/sdk/test/custom/intents/yes.yaml deleted file mode 100644 index 92072da0..00000000 --- a/sdk/test/custom/intents/yes.yaml +++ /dev/null @@ -1,6 +0,0 @@ -trainingPhrases: -- "y" -- ui -- ouep -- ouais -- oui diff --git a/sdk/test/custom/scenes/home_lvl1_AccountLinking.yaml b/sdk/test/custom/scenes/home_lvl1_AccountLinking.yaml deleted file mode 100644 index a3fb2cf1..00000000 --- a/sdk/test/custom/scenes/home_lvl1_AccountLinking.yaml +++ /dev/null @@ -1,19 +0,0 @@ -conditionalEvents: -- condition: session.params.AccountLinkingSlot == "LINKED" - transitionToScene: home_members_lvl2 -- condition: session.params.AccountLinkingSlot == "ERROR" - transitionToScene: home_lvl1 -- condition: session.params.AccountLinkingSlot == "REJECTED" - transitionToScene: home_lvl1 -slots: -- commitBehavior: - writeSessionParam: AccountLinkingSlot - config: - '@type': type.googleapis.com/google.actions.conversation.v3.SignInSpec - opt_context: "" - defaultValue: - sessionParam: AccountLinkingSlot - name: AccountLinkingSlot - required: true - type: - name: actions.type.AccountLinking diff --git a/sdk/test/custom/types/string.yaml b/sdk/test/custom/types/string.yaml deleted file mode 100644 index 63ddd907..00000000 --- a/sdk/test/custom/types/string.yaml +++ /dev/null @@ -1 +0,0 @@ -freeText: {} diff --git a/sdk/test/manifest.yaml b/sdk/test/manifest.yaml deleted file mode 100644 index d847aecb..00000000 --- a/sdk/test/manifest.yaml +++ /dev/null @@ -1 +0,0 @@ -version: "1.0" diff --git a/sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml similarity index 100% rename from sdk/test/webhooks/ActionsOnGoogleFulfillment.yaml rename to sdk/webhooks/ActionsOnGoogleFulfillment.yaml diff --git a/test/dev/.eslintrc.json b/test/dev/.eslintrc.json deleted file mode 100644 index c5624c4e..00000000 --- a/test/dev/.eslintrc.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "env": { - "browser": true, - "es2021": true - }, - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": 12, - "sourceType": "module" - }, - "plugins": [ - "@typescript-eslint" - ], - "rules": { - } -} diff --git a/test/dev/package-lock.json b/test/dev/package-lock.json deleted file mode 100644 index 3677cf9a..00000000 --- a/test/dev/package-lock.json +++ /dev/null @@ -1,3094 +0,0 @@ -{ - "name": "lis-mon-livre-test", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@assistant/actions": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@assistant/actions/-/actions-0.1.0.tgz", - "integrity": "sha512-V3PUGj7j/8Gq4VPFwP40k6AnsJaV2nnViuGskYnCe8sKLgCTzeGsOKnoGJgEEjI3ETm5mPd8ym3/HoksRODMNw==", - "dev": true, - "requires": { - "google-gax": "^2.9.2" - } - }, - "@assistant/conversation-testing": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@assistant/conversation-testing/-/conversation-testing-1.0.0.tgz", - "integrity": "sha512-9NZ3q1PI/FXegVaF+Kt2M/z2tWcDSPZ8aQ/UBYqtmYk0xSQX3ZRNhg9FWEGeAGL7+1tV4aRRkBylTvUUOGivrQ==", - "dev": true, - "requires": { - "@assistant/actions": "0.1.0", - "@types/chai": "^4.1.4", - "@types/i18n": "^0.8.6", - "@types/js-yaml": "^3.12.5", - "@types/node": "^10.9.4", - "@types/promise.prototype.finally": "^2.0.3", - "chai": "^4.2.0", - "google-auth-library": "^6.1.2", - "grpc": "^1.24.0", - "i18n": "^0.8.3", - "js-yaml": "^3.14.0", - "promise.prototype.finally": "^3.1.1", - "ts-node": "^7.0.1" - }, - "dependencies": { - "@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - } - } - } - }, - "@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true - }, - "@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", - "dev": true, - "requires": { - "@cspotcode/source-map-consumer": "0.8.0" - } - }, - "@eslint/eslintrc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.3.tgz", - "integrity": "sha512-DHI1wDPoKCBPoLZA3qDR91+3te/wDSc1YhKg3jR8NxKKRJq2hwHwcWv31cSwSYvIBrmbENoYMWcenW8uproQqg==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.0.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - } - }, - "@grpc/grpc-js": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.4.1.tgz", - "integrity": "sha512-/chkA48TdAvATHA7RXJPeHQLdfFhpu51974s8htjO/XTDHA41j5+SkR5Io+lr9XsLmkZD6HxLyRAFGmA9wjO2w==", - "dev": true, - "requires": { - "@grpc/proto-loader": "^0.6.4", - "@types/node": ">=12.12.47" - } - }, - "@grpc/proto-loader": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.6.tgz", - "integrity": "sha512-cdMaPZ8AiFz6ua6PUbP+LKbhwJbFXnrQ/mlnKGUyzDUZ3wp7vPLksnmLCBX6SHgSmjX7CbNVNLFYD5GmmjO4GQ==", - "dev": true, - "requires": { - "@types/long": "^4.0.1", - "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", - "protobufjs": "^6.10.0", - "yargs": "^16.1.1" - } - }, - "@humanwhocodes/config-array": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.6.0.tgz", - "integrity": "sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", - "dev": true - }, - "@mapbox/node-pre-gyp": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.6.tgz", - "integrity": "sha512-qK1ECws8UxuPqOA8F5LFD90vyVU33W7N3hGfgsOVfrJaRVc8McC3JClTDHpeSbL9CBrOHly/4GsNPAvIgNZE+g==", - "dev": true, - "requires": { - "detect-libc": "^1.0.3", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.5", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=", - "dev": true - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "dev": true - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "dev": true - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=", - "dev": true - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "dev": true, - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=", - "dev": true - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=", - "dev": true - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=", - "dev": true - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=", - "dev": true - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", - "dev": true - }, - "@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", - "dev": true - }, - "@types/bytebuffer": { - "version": "5.0.42", - "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.42.tgz", - "integrity": "sha512-lEgKojWUAc/MG2t649oZS5AfYFP2xRNPoDuwDBlBMjHXd8MaGPgFgtCXUK7inZdBOygmVf10qxc1Us8GXC96aw==", - "dev": true, - "requires": { - "@types/long": "*", - "@types/node": "*" - } - }, - "@types/chai": { - "version": "4.2.22", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.22.tgz", - "integrity": "sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ==", - "dev": true - }, - "@types/i18n": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@types/i18n/-/i18n-0.8.8.tgz", - "integrity": "sha512-RI4LFAraGrimMTxXkediCMXGVLC6ksXIIo3U+d3E4n+Mhw3uIDbmokO7DHlPB/eu6Tn6KBv4IUE1WrrEDRdNUQ==", - "dev": true - }, - "@types/js-yaml": { - "version": "3.12.7", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.7.tgz", - "integrity": "sha512-S6+8JAYTE1qdsc9HMVsfY7+SgSuUU/Tp6TYTmITW0PZxiyIMvol3Gy//y69Wkhs0ti4py5qgR3uZH6uz/DNzJQ==", - "dev": true - }, - "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true - }, - "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==", - "dev": true - }, - "@types/mocha": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.0.0.tgz", - "integrity": "sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==", - "dev": true - }, - "@types/node": { - "version": "16.11.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.4.tgz", - "integrity": "sha512-TMgXmy0v2xWyuCSCJM6NCna2snndD8yvQF67J29ipdzMcsPa9u+o0tjF5+EQNdhcuZplYuouYqpc4zcd5I6amQ==", - "dev": true - }, - "@types/promise.prototype.finally": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/promise.prototype.finally/-/promise.prototype.finally-2.0.4.tgz", - "integrity": "sha512-bkzsMz11tGI5r/ZhJIVI1+QSWKKBcX/Llv0zoM2ufOH+o/3sLXwE5xCW0OUX81xPa4EGOyPKFlNrH9GH+IF4lg==", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.1.0.tgz", - "integrity": "sha512-bekODL3Tqf36Yz8u+ilha4zGxL9mdB6LIsIoMAvvC5FAuWo4NpZYXtCbv7B2CeR1LhI/lLtLk+q4tbtxuoVuCg==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "5.1.0", - "@typescript-eslint/scope-manager": "5.1.0", - "debug": "^4.3.2", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.2.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - } - } - }, - "@typescript-eslint/experimental-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.1.0.tgz", - "integrity": "sha512-ovE9qUiZMOMgxQAESZsdBT+EXIfx/YUYAbwGUI6V03amFdOOxI9c6kitkgRvLkJaLusgMZ2xBhss+tQ0Y1HWxA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.1.0", - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/typescript-estree": "5.1.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "dependencies": { - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - } - } - }, - "@typescript-eslint/parser": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.1.0.tgz", - "integrity": "sha512-vx1P+mhCtYw3+bRHmbalq/VKP2Y3gnzNgxGxfEWc6OFpuEL7iQdAeq11Ke3Rhy8NjgB+AHsIWEwni3e+Y7djKA==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.1.0", - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/typescript-estree": "5.1.0", - "debug": "^4.3.2" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.1.0.tgz", - "integrity": "sha512-yYlyVjvn5lvwCL37i4hPsa1s0ORsjkauhTqbb8MnpvUs7xykmcjGqwlNZ2Q5QpoqkJ1odlM2bqHqJwa28qV6Tw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/visitor-keys": "5.1.0" - } - }, - "@typescript-eslint/types": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.1.0.tgz", - "integrity": "sha512-sEwNINVxcB4ZgC6Fe6rUyMlvsB2jvVdgxjZEjQUQVlaSPMNamDOwO6/TB98kFt4sYYfNhdhTPBEQqNQZjMMswA==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.1.0.tgz", - "integrity": "sha512-SSz+l9YrIIsW4s0ZqaEfnjl156XQ4VRmJsbA0ZE1XkXrD3cRpzuZSVCyqeCMR3EBjF27IisWakbBDGhGNIOvfQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/visitor-keys": "5.1.0", - "debug": "^4.3.2", - "globby": "^11.0.4", - "is-glob": "^4.0.3", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.1.0.tgz", - "integrity": "sha512-uqNXepKBg81JVwjuqAxYrXa1Ql/YDzM+8g/pS+TCPxba0wZttl8m5DkrasbfnmJGHs4lQ2jTbcZ5azGhI7kK+w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.1.0", - "eslint-visitor-keys": "^3.0.0" - } - }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true - }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "dev": true - }, - "are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - }, - "dependencies": { - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - } - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true - }, - "ascli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", - "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", - "dev": true, - "requires": { - "colour": "~0.7.1", - "optjs": "~3.2.2" - } - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", - "dev": true - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=", - "dev": true - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "bytebuffer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", - "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", - "dev": true, - "requires": { - "long": "~3" - }, - "dependencies": { - "long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", - "dev": true - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, - "colour": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz", - "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "dev": true, - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.1.0.tgz", - "integrity": "sha512-JZvNneArGSUsluHWJ8g8MMs3CfIEzwaLx9KyH4tZ2i+R2/rPWzL8c0zg3rHdwYVpN/1sB9gqnjHwz9HoeJpGHw==", - "dev": true, - "requires": { - "@eslint/eslintrc": "^1.0.3", - "@humanwhocodes/config-array": "^0.6.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^6.0.0", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.0.0", - "espree": "^9.0.0", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.2.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - } - } - }, - "eslint-scope": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-6.0.0.tgz", - "integrity": "sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz", - "integrity": "sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q==", - "dev": true - }, - "espree": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.0.0.tgz", - "integrity": "sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ==", - "dev": true, - "requires": { - "acorn": "^8.5.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.0.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fast-text-encoding": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", - "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==", - "dev": true - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", - "dev": true - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "gauge": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.1.tgz", - "integrity": "sha512-6STz6KdQgxO4S/ko+AbjlFGGdGcknluoqU+79GOFCDqqyYj5OanQf9AjxwN0jCidtT+ziPMmPSt9E4hfQ0CwIQ==", - "dev": true, - "requires": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1 || ^2.0.0", - "strip-ansi": "^3.0.1 || ^4.0.0", - "wide-align": "^1.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "gaxios": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.2.tgz", - "integrity": "sha512-T+ap6GM6UZ0c4E6yb1y/hy2UB6hTrqhglp3XfmU9qbLCGRYhLVV5aRPpC4EmoG8N8zOnkYCgoBz+ScvGAARY6Q==", - "dev": true, - "requires": { - "abort-controller": "^3.0.0", - "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.1" - } - }, - "gcp-metadata": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.1.tgz", - "integrity": "sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==", - "dev": true, - "requires": { - "gaxios": "^4.0.0", - "json-bigint": "^1.0.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "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" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - } - } - }, - "google-auth-library": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.6.tgz", - "integrity": "sha512-Q+ZjUEvLQj/lrVHF/IQwRo6p3s8Nc44Zk/DALsN+ac3T4HY/g/3rrufkgtl+nZ1TW7DNAw5cTChdVp4apUXVgQ==", - "dev": true, - "requires": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - } - }, - "google-gax": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.28.0.tgz", - "integrity": "sha512-kuqc8a4+CTCMBcF3tlOL7Sa74JWkTzcZxatAQTCVK35WToXkHnJ0qncFOJuegUv3EbV9IQY4j/+NZdFLv+lbTA==", - "dev": true, - "requires": { - "@grpc/grpc-js": "~1.4.0", - "@grpc/proto-loader": "^0.6.1", - "@types/long": "^4.0.0", - "abort-controller": "^3.0.0", - "duplexify": "^4.0.0", - "fast-text-encoding": "^1.0.3", - "google-auth-library": "^7.6.1", - "is-stream-ended": "^0.1.4", - "node-fetch": "^2.6.1", - "object-hash": "^2.1.1", - "proto3-json-serializer": "^0.1.1", - "protobufjs": "6.11.2", - "retry-request": "^4.0.0" - }, - "dependencies": { - "google-auth-library": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.10.1.tgz", - "integrity": "sha512-nQxgM1ZopUMcpMnu95kOSzI+9tJl4YDOZJomSTBGlRLpxfBopdwto7WvzoI87HuN0nQqVETgOsHi/C/po1rppA==", - "dev": true, - "requires": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - } - } - } - }, - "google-p12-pem": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.2.tgz", - "integrity": "sha512-tjf3IQIt7tWCDsa0ofDQ1qqSCNzahXDxdAGJDbruWqu3eCg5CKLYKN+hi0s6lfvzYZ1GDVr+oDF9OOWlDSdf0A==", - "dev": true, - "requires": { - "node-forge": "^0.10.0" - } - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "grpc": { - "version": "1.24.11", - "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.24.11.tgz", - "integrity": "sha512-8/AQdFCzCeCDWW3SoaMNp6ccbRvTQEH1O1u1uFtt29eWsg5gSZCJ3m6fbkduEIh3smY7WAPP+LgVJ5n3nZRxcA==", - "dev": true, - "requires": { - "@mapbox/node-pre-gyp": "^1.0.4", - "@types/bytebuffer": "^5.0.40", - "lodash.camelcase": "^4.3.0", - "lodash.clone": "^4.5.0", - "nan": "^2.13.2", - "protobufjs": "^5.0.3" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "protobufjs": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz", - "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==", - "dev": true, - "requires": { - "ascli": "~1", - "bytebuffer": "~5", - "glob": "^7.0.5", - "yargs": "^3.10.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", - "dev": true, - "requires": { - "camelcase": "^2.0.1", - "cliui": "^3.0.3", - "decamelize": "^1.1.1", - "os-locale": "^1.4.0", - "string-width": "^1.0.1", - "window-size": "^0.1.4", - "y18n": "^3.2.0" - } - } - } - }, - "gtoken": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.3.1.tgz", - "integrity": "sha512-yqOREjzLHcbzz1UrQoxhBtpk8KjrVhuqPE7od1K2uhyxG2BHjKZetlbLw/SPZak/QqTIQW+addS+EcjqQsZbwQ==", - "dev": true, - "requires": { - "gaxios": "^4.0.0", - "google-p12-pem": "^3.0.3", - "jws": "^4.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "i18n": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/i18n/-/i18n-0.8.6.tgz", - "integrity": "sha512-aMsJq8i1XXrb+BBsgmJBwak9mr69zPEIAUPb6c5yw2G/O4k1Q52lBxL+agZdQDN/RGf1ylQzrCswsOOgIiC1FA==", - "dev": true, - "requires": { - "debug": "*", - "make-plural": "^6.0.1", - "math-interval-parser": "^2.0.1", - "messageformat": "^2.3.0", - "mustache": "*", - "sprintf-js": "^1.1.2" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "is-stream-ended": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", - "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==", - "dev": true - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "is-weakref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "dev": true, - "requires": { - "bignumber.js": "^9.0.0" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "dev": true, - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "dev": true, - "requires": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", - "dev": true - }, - "lodash.clone": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", - "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "make-plural": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-6.2.2.tgz", - "integrity": "sha512-8iTuFioatnTTmb/YJjywkVIHLjcwkFD9Ms0JpxjEm9Mo8eQYkh1z+55dwv4yc1jQ8ftVBxWQbihvZL1DfzGGWA==", - "dev": true - }, - "math-interval-parser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/math-interval-parser/-/math-interval-parser-2.0.1.tgz", - "integrity": "sha512-VmlAmb0UJwlvMyx8iPhXUDnVW1F9IrGEd9CIOmv+XL8AErCUUuozoDMrgImvnYt2A+53qVX/tPW6YJurMKYsvA==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "messageformat": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/messageformat/-/messageformat-2.3.0.tgz", - "integrity": "sha512-uTzvsv0lTeQxYI2y1NPa1lItL5VRI8Gb93Y2K2ue5gBPyrbJxfDi/EYWxh2PKv5yO42AJeeqblS9MJSh/IEk4w==", - "dev": true, - "requires": { - "make-plural": "^4.3.0", - "messageformat-formatters": "^2.0.1", - "messageformat-parser": "^4.1.2" - }, - "dependencies": { - "make-plural": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz", - "integrity": "sha512-xTYd4JVHpSCW+aqDof6w/MebaMVNTVYBZhbB/vi513xXdiPT92JMVCo0Jq8W2UZnzYRFeVbQiQ+I25l13JuKvA==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - } - } - }, - "messageformat-formatters": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/messageformat-formatters/-/messageformat-formatters-2.0.1.tgz", - "integrity": "sha512-E/lQRXhtHwGuiQjI7qxkLp8AHbMD5r2217XNe/SREbBlSawe0lOqsFb7rflZJmlQFSULNLIqlcjjsCPlB3m3Mg==", - "dev": true - }, - "messageformat-parser": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-4.1.3.tgz", - "integrity": "sha512-2fU3XDCanRqeOCkn7R5zW5VQHWf+T3hH65SzuqRvjatBK7r4uyFa5mEX+k6F9Bd04LVM5G4/BHBTUJsOdW7uyg==", - "dev": true - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "minipass": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", - "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "mocha": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz", - "integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==", - "dev": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.2", - "debug": "4.3.2", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.7", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "nanoid": "3.1.25", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.1.5", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "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-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "mustache": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", - "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", - "dev": true - }, - "nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "dev": true - }, - "nanoid": { - "version": "3.1.25", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", - "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node-fetch": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", - "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", - "dev": true - }, - "nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "dev": true, - "requires": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", - "dev": true - }, - "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "optjs": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", - "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=", - "dev": true - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "promise.prototype.finally": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/promise.prototype.finally/-/promise.prototype.finally-3.1.3.tgz", - "integrity": "sha512-EXRF3fC9/0gz4qkt/f5EP5iW4kj9oFpBICNpCNOb/52+8nlHIX07FPLbi/q4qYBQ1xZqivMzTpNQSnArVASolQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "proto3-json-serializer": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-0.1.4.tgz", - "integrity": "sha512-bFzdsKU/zaTobWrRxRniMZIzzcgKYlmBWL1gAcTXZ2M7TQTGPI0JoYYs6bN7tpWj59ZCfwg7Ii/A2e8BbQGYnQ==", - "dev": true - }, - "protobufjs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", - "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", - "dev": true, - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "retry-request": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.2.2.tgz", - "integrity": "sha512-xA93uxUD/rogV7BV59agW/JHPGXeREMWiZc9jhcwY4YdZ7QOtC7qbomYg0n4wyk2lJhggjvKvhNX8wln/Aldhg==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "extend": "^3.0.2" - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "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 - }, - "source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true - }, - "ts-node": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", - "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "0.7.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "yn": "3.1.1" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - } - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dev": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", - "dev": true - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "workerpool": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", - "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "dependencies": { - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - } - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } - } -} diff --git a/test/dev/package.json b/test/dev/package.json deleted file mode 100644 index 62eccfc8..00000000 --- a/test/dev/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "lis-mon-livre-test", - "version": "1.0.0", - "description": "", - "private": true, - "scripts": { - "lint": "eslint \"test/*.ts\"", - "enable-activity-controls": "env GOOGLE_APPLICATION_CREDENTIALS=$PWD/service_account.json web-and-app-activity-controls", - "test": "npm run lint && env GOOGLE_APPLICATION_CREDENTIALS=$PWD/service_account.json PROJECT_ID=$(cat $PWD/service_account.json| jq -r '.project_id') mocha --recursive --require ts-node/register test/*.ts", - "test:file": "npm run lint && env GOOGLE_APPLICATION_CREDENTIALS=$PWD/service_account.json PROJECT_ID=$(cat $PWD/service_account.json| jq -r '.project_id') mocha --recursive --require ts-node/register" - }, - "author": "", - "license": "ISC", - "devDependencies": { - "@assistant/conversation-testing": "^1.0.0", - "@types/mocha": "^9.0.0", - "@types/node": "^16.11.4", - "@typescript-eslint/eslint-plugin": "^5.1.0", - "@typescript-eslint/parser": "^5.1.0", - "chai": "^4.3.4", - "eslint": "^8.1.0", - "mocha": "^9.1.3", - "ts-node": "^10.4.0", - "typescript": "^4.4.4" - } -} diff --git a/test/dev/test/constant.ts b/test/dev/test/constant.ts deleted file mode 100644 index bba04e70..00000000 --- a/test/dev/test/constant.ts +++ /dev/null @@ -1,18 +0,0 @@ - -import {env} from 'process'; -import {ok} from 'assert'; - -export const DEFAULT_LOCALE = 'fr-FR'; -export const DEFAULT_SURFACE = 'PHONE'; -export const HOME_PROMPT = "Bienvenue dans Valentin Audio."; -export const MEMBER_PROMPT = "Les commandes possibles sont: sélection, lecture, recherche. Que voulez-vous faire ?"; - -export const PROJECT_ID = env['PROJECT_ID'] || ''; -export const TRIGGER_PHRASE = 'Parler avec valentin audio dev'; - - -console.log(`PROJECT_ID=${PROJECT_ID}`); - -ok(PROJECT_ID, 'no PROJECT_ID'); - - diff --git a/test/dev/test/test1.ts b/test/dev/test/test1.ts deleted file mode 100644 index fe7185ed..00000000 --- a/test/dev/test/test1.ts +++ /dev/null @@ -1,44 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; - -const TEST_NUM = 1; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('trigger only', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/dev/test/test10.ts b/test/dev/test/test10.ts deleted file mode 100644 index df8d7c46..00000000 --- a/test/dev/test/test10.ts +++ /dev/null @@ -1,58 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as chai from 'chai'; - -const TEST_NUM = 10; -import * as fs from 'fs'; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - - await test.sendQuery(`sélections`); - test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre. Que voulez-vous faire ?`); - - await test.sendQuery(`selections thématiques`); - test.assertSpeech(`J'ai trouvé 2 sélections.\nnuméro 1 : liste d'essai de Philosophie.\nnuméro 2 : liste de l'auteur Emile Zola.\n\nPour choisir une sélection, dites son numéro.`); - - await test.sendQuery(`numéro 2`); - - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('thematic selection', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/dev/test/test11.ts b/test/dev/test/test11.ts deleted file mode 100644 index fcee609e..00000000 --- a/test/dev/test/test11.ts +++ /dev/null @@ -1,58 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as chai from 'chai'; - -const TEST_NUM = 11; -import * as fs from 'fs'; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - - await test.sendQuery(`sélections`); - test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre. Que voulez-vous faire ?`); - - await test.sendQuery(`selections par genre`); - - test.assertSpeech(`J'ai trouvé 2 sélections.\nnuméro 1 : liste d'essai de Philosophie.\nnuméro 2 : roman.\n\nPour choisir une sélection, dites son numéro.`); - - await test.sendQuery(`numéro 2`); - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('genre selection', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/dev/test/test12.ts b/test/dev/test/test12.ts deleted file mode 100644 index f627359d..00000000 --- a/test/dev/test/test12.ts +++ /dev/null @@ -1,67 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as fs from 'fs'; -import * as chai from 'chai'; - -const TEST_NUM = 12; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // RECHERCHE - - await test.sendQuery('recherche'); - - test.assertSpeech(`Que voulez-vous écouter ?`); - - await test.sendQuery('zola'); - - await test.assertSpeech(`J'ai trouvé 2 publications.\nnuméro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n`); - - await test.sendQuery('0'); - - await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. J'ai trouvé 2 publications.\nnuméro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n`); - - test.assertScene('select_publication'); - - await test.sendQuery('revenir au menu principal'); - - test.assertSpeech(MEMBER_PROMPT); - - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('search with zola query bad number choice and then stop it', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/dev/test/test13.ts b/test/dev/test/test13.ts deleted file mode 100644 index 9d1ad327..00000000 --- a/test/dev/test/test13.ts +++ /dev/null @@ -1,60 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as chai from 'chai'; - -const TEST_NUM = 13; -import * as fs from 'fs'; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - - await test.sendQuery(`sélections`); - test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre. Que voulez-vous faire ?`); - - await test.sendQuery(`selections par genre`); - - test.assertSpeech(``); - - await test.sendQuery(`revenir au menu principal`); - - test.assertSpeech(MEMBER_PROMPT); - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('genre selection then stop', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/dev/test/test2.ts b/test/dev/test/test2.ts deleted file mode 100644 index 68eb2dcc..00000000 --- a/test/dev/test/test2.ts +++ /dev/null @@ -1,57 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; - -const TEST_NUM = 2; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // RECHERCHE - - await test.sendQuery('recherche'); - - test.assertSpeech(`Que voulez-vous écouter ?`); - - await test.sendQuery('test avec aucune publication renvoyées'); - - await test.assertSpeech(`Aucun résultat trouvé. Que voulez-vous écouter ? Par exemple Zola.`); - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('search with bad query', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/dev/test/test3-2.ts b/test/dev/test/test3-2.ts deleted file mode 100644 index a36d4818..00000000 --- a/test/dev/test/test3-2.ts +++ /dev/null @@ -1,74 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; - -const TEST_NUM = 302; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // RECHERCHE - - await test.sendQuery('recherche'); - - test.assertSpeech(`Que voulez-vous écouter ?`); - - await test.sendQuery('*'); - - test.assertSpeech(`J'ai trouvé 8 publications.\nVous êtes sur la page 1.\nnuméro 1 : vingt mille lieu sous les mers de Jule Verne.\nnuméro 2 : La chevre de monsieur segin de Alphonse Daudet.\nnuméro 3 : peau d'âne de Charles Perrault.\nnuméro 4 : Thérèse Raquin de Emile Zola.\nnuméro 5 : Du contrat social de Rousseau.\n\nPour choisir l'une des publications, dites son numéro.`); - - await test.sendQuery('0'); - - test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. J'ai trouvé 8 publications.\nVous êtes sur la page 1.\nnuméro 1 : vingt mille lieu sous les mers de Jule Verne.\nnuméro 2 : La chevre de monsieur segin de Alphonse Daudet.\nnuméro 3 : peau d'âne de Charles Perrault.\nnuméro 4 : Thérèse Raquin de Emile Zola.\nnuméro 5 : Du contrat social de Rousseau.\n\nPour choisir l'une des publications, dites son numéro.`); - - await test.sendQuery('suivant'); - - test.assertSpeech("Vous êtes sur la page 2.\nnuméro 1 : la guerre des boutons de pergaud.\nnuméro 2 : le prince de Nicolas Machiavel.\nnuméro 3 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n"); - - await test.sendQuery('suivant'); - - test.assertSpeech("Il n'y a pas de page suivante, je vais répéter la dernière page. Vous êtes sur la page 2.\nnuméro 1 : la guerre des boutons de pergaud.\nnuméro 2 : le prince de Nicolas Machiavel.\nnuméro 3 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n"); - - await test.sendQuery('repete'); - - test.assertSpeech("Vous êtes sur la page 2.\nnuméro 1 : la guerre des boutons de pergaud.\nnuméro 2 : le prince de Nicolas Machiavel.\nnuméro 3 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n"); - - test.assertScene('select_publication'); - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('search with zola query', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/dev/test/test3.ts b/test/dev/test/test3.ts deleted file mode 100644 index 720aacec..00000000 --- a/test/dev/test/test3.ts +++ /dev/null @@ -1,63 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; - -const TEST_NUM = 3; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // RECHERCHE - - await test.sendQuery('recherche'); - - test.assertSpeech(`Que voulez-vous écouter ?`); - - await test.sendQuery('zola'); - - await test.assertSpeech(`J'ai trouvé 2 publications.\nnuméro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n`); - - await test.sendQuery('0'); - - await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. J'ai trouvé 2 publications.\nnuméro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n`); - - test.assertScene('select_publication'); - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('search with zola query', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/dev/test/test4.ts b/test/dev/test/test4.ts deleted file mode 100644 index 1424aa0d..00000000 --- a/test/dev/test/test4.ts +++ /dev/null @@ -1,258 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as fs from 'fs'; -import * as chai from 'chai'; - -const TEST_NUM = 4; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // RECHERCHE - - await test.sendQuery('recherche'); - - test.assertSpeech(`Que voulez-vous écouter ?`); - - await test.sendQuery('zola'); - - await test.assertSpeech(`J'ai trouvé 2 publications.\nnuméro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n`); - - await test.sendQuery('0'); - - await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. J'ai trouvé 2 publications.\nnuméro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n`); - - test.assertScene('select_publication'); - - await test.sendQuery('1'); - - const resp: any = test.getLatestResponse(); - - // console.log(resp); - // console.log(inspect(resp, {showHidden: false, depth: null, colors: true})); - // - - chai.expect(JSON.stringify(resp.output.actionsBuilderPrompt.content)).to.equal(JSON.stringify({ - "media": { - "optionalMediaControls": [ - "PAUSED", - "STOPPED" - ], - "mediaObjects": [ - { - "name": "Thérèse Raquin - 1", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap01-03.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 2", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap04-06.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 3", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap07-09.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 4", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap10-12.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 5", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap13-16.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 6", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap17-18.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 7", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap19-20.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 8", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap21-22.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 9", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap23-25.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 10", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap26-27.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 11", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap28-29.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 12", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap30-32.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - } - ], - "startOffset": { - "seconds": "0", - "nanos": 0 - }, - "mediaType": "AUDIO" - }, - "content": "media" - })); - - test.assertScene('player'); - - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('search with zola query bad number choice', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/dev/test/test5.ts b/test/dev/test/test5.ts deleted file mode 100644 index e2157e32..00000000 --- a/test/dev/test/test5.ts +++ /dev/null @@ -1,221 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as chai from 'chai'; - -const TEST_NUM = 5; -import * as fs from 'fs'; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // 123 : player therese_raquin_emile_zola.json - await test.sendQuery(`test player 123`); - test.assertSpeech(`test player 123 ${MEMBER_PROMPT}`); - - // RECHERCHE - - await test.sendQuery('lecture'); - test.assertSpeech(`Voulez-vous reprendre la lecture là où elle s'était arrêtée ?`); - - await test.sendQuery('oui'); - - // console.log(test.getLatestResponse()); - - const media = test.getMedia(); - - // console.log(media); - - chai.expect(media).to.deep.equal({ - "optionalMediaControls": [ - "PAUSED", - "STOPPED" - ], - "mediaObjects": [ - { - "name": "Thérèse Raquin - 3", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap07-09.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 4", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap10-12.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 5", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap13-16.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 6", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap17-18.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 7", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap19-20.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 8", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap21-22.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 9", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap23-25.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 10", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap26-27.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 11", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap28-29.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 12", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap30-32.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - } - ], - "startOffset": { - "seconds": "123", - "nanos": 0 - }, - "mediaType": "AUDIO" - }); - - - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('remaining playing', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/dev/test/test6.ts b/test/dev/test/test6.ts deleted file mode 100644 index f7285132..00000000 --- a/test/dev/test/test6.ts +++ /dev/null @@ -1,248 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as chai from 'chai'; - -const TEST_NUM = 6; -import * as fs from 'fs'; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // 123 : player therese_raquin_emile_zola.json - await test.sendQuery(`test player 123`); - test.assertSpeech(`test player 123 ${MEMBER_PROMPT}`); - - // RECHERCHE - - await test.sendQuery('lecture'); - test.assertSpeech(`Voulez-vous reprendre la lecture là où elle s'était arrêtée ?`); - // console.log(test.getLatestResponse()); - - await test.sendQuery('non'); - const media = test.getMedia(); - - // console.log(media); - -// fs.writeFileSync('/tmp/media.json', JSON.stringify(media)); - chai.expect(media).to.deep.equal({ - "optionalMediaControls": [ - "PAUSED", - "STOPPED" - ], - "mediaObjects": [ - { - "name": "Thérèse Raquin - 1", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap01-03.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 2", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap04-06.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 3", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap07-09.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 4", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap10-12.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 5", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap13-16.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 6", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap17-18.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 7", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap19-20.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 8", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap21-22.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 9", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap23-25.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 10", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap26-27.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 11", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap28-29.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 12", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap30-32.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - } - ], - "startOffset": { - "seconds": "0", - "nanos": 0 - }, - "mediaType": "AUDIO" - }); - - - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('playing from beginning', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/dev/test/test7.ts b/test/dev/test/test7.ts deleted file mode 100644 index 6d8825dd..00000000 --- a/test/dev/test/test7.ts +++ /dev/null @@ -1,254 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as chai from 'chai'; - -const TEST_NUM = 7; -import * as fs from 'fs'; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // 123 : player therese_raquin_emile_zola.json - await test.sendQuery(`test player 123`); - test.assertSpeech(`test player 123 ${MEMBER_PROMPT}`); - - // RECHERCHE - - await test.sendQuery('lecture'); - test.assertSpeech(`Voulez-vous reprendre la lecture là où elle s'était arrêtée `); - - await test.sendQuery('test'); - const resp = test.getLatestResponse(); - chai.expect(test.getSpeech()).to.equal("je n'ai pas compris. Que voulez-vous dire ?"); - test.assertSpeech("je n'ai pas compris. Que voulez-vous dire ?"); - - let media = test.getMedia(); - chai.expect(media).to.equal(undefined); - - await test.sendQuery('non'); - - - media = test.getMedia(); -// fs.writeFileSync('/tmp/media.json', JSON.stringify(media)); - chai.expect(media).to.deep.equal({ - "optionalMediaControls": [ - "PAUSED", - "STOPPED" - ], - "mediaObjects": [ - { - "name": "Thérèse Raquin - 1", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap01-03.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 2", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap04-06.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 3", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap07-09.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 4", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap10-12.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 5", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap13-16.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 6", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap17-18.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 7", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap19-20.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 8", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap21-22.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 9", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap23-25.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 10", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap26-27.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 11", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap28-29.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 12", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap30-32.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - } - ], - "startOffset": { - "seconds": "0", - "nanos": 0 - }, - "mediaType": "AUDIO" - }); - - - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('playing bad yes or no', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/dev/test/test8.ts b/test/dev/test/test8.ts deleted file mode 100644 index a2c27d76..00000000 --- a/test/dev/test/test8.ts +++ /dev/null @@ -1,256 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as chai from 'chai'; - -const TEST_NUM = 8; -import * as fs from 'fs'; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // 123 : player therese_raquin_emile_zola.json - await test.sendQuery(`test player 123`); - test.assertSpeech(`test player 123 ${MEMBER_PROMPT}`); - - // RECHERCHE - - await test.sendQuery('lecture'); - test.assertSpeech(`Voulez-vous reprendre la lecture là où elle s'était arrêtée `); - - await test.sendQuery('non'); - - const media = test.getMedia(); -// fs.writeFileSync('/tmp/media.json', JSON.stringify(media)); - chai.expect(media).to.deep.equal({ - "optionalMediaControls": [ - "PAUSED", - "STOPPED" - ], - "mediaObjects": [ - { - "name": "Thérèse Raquin - 1", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap01-03.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 2", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap04-06.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 3", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap07-09.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 4", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap10-12.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 5", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap13-16.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 6", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap17-18.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 7", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap19-20.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 8", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap21-22.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 9", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap23-25.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 10", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap26-27.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 11", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap28-29.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 12", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap30-32.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - } - ], - "startOffset": { - "seconds": "0", - "nanos": 0 - }, - "mediaType": "AUDIO" - }); - - // await test.sendQuery('reprend la lecture'); - - // media = test.getMedia(); - // console.log(media); - - // // media === undefined - // // test doesn't handle intent during media playing - // // It's a TEST LIMITATION - // // - // // same - // chai.expect(media).to.equal(undefined); - - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('player resume listening | repprendre la lecture', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/dev/test/test9.ts b/test/dev/test/test9.ts deleted file mode 100644 index f5fbed22..00000000 --- a/test/dev/test/test9.ts +++ /dev/null @@ -1,133 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as chai from 'chai'; - -const TEST_NUM = 9; -import * as fs from 'fs'; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - - await test.sendQuery(`sélections`); - test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre. Que voulez-vous faire ?`); - - await test.sendQuery(`ma liste`); - test.assertSpeech(`numéro 1 : L'assommoir de Emile Zola.\nnuméro 2 : Du contrat social de Rousseau.\n\nPour choisir l'une des publications, dites son numéro.\n`); - - await test.sendQuery(`2`); - - const media = test.getMedia(); - // fs.writeFileSync('/tmp/media.json', JSON.stringify(media)); - chai.expect(media).to.deep.equal({ - "optionalMediaControls": [ - "PAUSED", - "STOPPED" - ], - "mediaObjects": [ - { - "name": "Du contrat social - 1", - "description": "", - "url": "https://archive.org/download/Du-contrat-social/Du_contrat_social_livre1.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/d/db/Social_contract_rousseau_page.jpg", - "alt": "Du contrat social", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Du contrat social - 2", - "description": "", - "url": "https://archive.org/download/Du-contrat-social/Du_contrat_social_livre2.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/d/db/Social_contract_rousseau_page.jpg", - "alt": "Du contrat social", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Du contrat social - 3", - "description": "", - "url": "https://archive.org/download/Du-contrat-social/Du_contrat_social_livre3.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/d/db/Social_contract_rousseau_page.jpg", - "alt": "Du contrat social", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Du contrat social - 4", - "description": "", - "url": "https://archive.org/download/Du-contrat-social/Du_contrat_social_livre4.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/d/db/Social_contract_rousseau_page.jpg", - "alt": "Du contrat social", - "height": 0, - "width": 0 - }, - "image": "large" - } - } - ], - "startOffset": { - "seconds": "0", - "nanos": 0 - }, - "mediaType": "AUDIO" - }); - - - - - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({ projectId: PROJECT_ID }); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('my list', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/prod/.eslintrc.json b/test/prod/.eslintrc.json deleted file mode 100644 index c5624c4e..00000000 --- a/test/prod/.eslintrc.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "env": { - "browser": true, - "es2021": true - }, - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": 12, - "sourceType": "module" - }, - "plugins": [ - "@typescript-eslint" - ], - "rules": { - } -} diff --git a/test/prod/package-lock.json b/test/prod/package-lock.json deleted file mode 100644 index be66871b..00000000 --- a/test/prod/package-lock.json +++ /dev/null @@ -1,3161 +0,0 @@ -{ - "name": "lis-mon-livre-test", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@assistant/actions": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@assistant/actions/-/actions-0.1.0.tgz", - "integrity": "sha512-V3PUGj7j/8Gq4VPFwP40k6AnsJaV2nnViuGskYnCe8sKLgCTzeGsOKnoGJgEEjI3ETm5mPd8ym3/HoksRODMNw==", - "dev": true, - "requires": { - "google-gax": "^2.9.2" - } - }, - "@assistant/conversation-testing": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@assistant/conversation-testing/-/conversation-testing-1.0.0.tgz", - "integrity": "sha512-9NZ3q1PI/FXegVaF+Kt2M/z2tWcDSPZ8aQ/UBYqtmYk0xSQX3ZRNhg9FWEGeAGL7+1tV4aRRkBylTvUUOGivrQ==", - "dev": true, - "requires": { - "@assistant/actions": "0.1.0", - "@types/chai": "^4.1.4", - "@types/i18n": "^0.8.6", - "@types/js-yaml": "^3.12.5", - "@types/node": "^10.9.4", - "@types/promise.prototype.finally": "^2.0.3", - "chai": "^4.2.0", - "google-auth-library": "^6.1.2", - "grpc": "^1.24.0", - "i18n": "^0.8.3", - "js-yaml": "^3.14.0", - "promise.prototype.finally": "^3.1.1", - "ts-node": "^7.0.1" - }, - "dependencies": { - "@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - } - } - } - }, - "@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true - }, - "@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", - "dev": true, - "requires": { - "@cspotcode/source-map-consumer": "0.8.0" - } - }, - "@eslint/eslintrc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.3.tgz", - "integrity": "sha512-DHI1wDPoKCBPoLZA3qDR91+3te/wDSc1YhKg3jR8NxKKRJq2hwHwcWv31cSwSYvIBrmbENoYMWcenW8uproQqg==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.0.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - } - }, - "@grpc/grpc-js": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.4.1.tgz", - "integrity": "sha512-/chkA48TdAvATHA7RXJPeHQLdfFhpu51974s8htjO/XTDHA41j5+SkR5Io+lr9XsLmkZD6HxLyRAFGmA9wjO2w==", - "dev": true, - "requires": { - "@grpc/proto-loader": "^0.6.4", - "@types/node": ">=12.12.47" - } - }, - "@grpc/proto-loader": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.6.tgz", - "integrity": "sha512-cdMaPZ8AiFz6ua6PUbP+LKbhwJbFXnrQ/mlnKGUyzDUZ3wp7vPLksnmLCBX6SHgSmjX7CbNVNLFYD5GmmjO4GQ==", - "dev": true, - "requires": { - "@types/long": "^4.0.1", - "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", - "protobufjs": "^6.10.0", - "yargs": "^16.1.1" - } - }, - "@humanwhocodes/config-array": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.6.0.tgz", - "integrity": "sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", - "dev": true - }, - "@mapbox/node-pre-gyp": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.6.tgz", - "integrity": "sha512-qK1ECws8UxuPqOA8F5LFD90vyVU33W7N3hGfgsOVfrJaRVc8McC3JClTDHpeSbL9CBrOHly/4GsNPAvIgNZE+g==", - "dev": true, - "requires": { - "detect-libc": "^1.0.3", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.5", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=", - "dev": true - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "dev": true - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "dev": true - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=", - "dev": true - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "dev": true, - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=", - "dev": true - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=", - "dev": true - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=", - "dev": true - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=", - "dev": true - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", - "dev": true - }, - "@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", - "dev": true - }, - "@types/bytebuffer": { - "version": "5.0.42", - "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.42.tgz", - "integrity": "sha512-lEgKojWUAc/MG2t649oZS5AfYFP2xRNPoDuwDBlBMjHXd8MaGPgFgtCXUK7inZdBOygmVf10qxc1Us8GXC96aw==", - "dev": true, - "requires": { - "@types/long": "*", - "@types/node": "*" - } - }, - "@types/chai": { - "version": "4.2.22", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.22.tgz", - "integrity": "sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ==", - "dev": true - }, - "@types/i18n": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@types/i18n/-/i18n-0.8.8.tgz", - "integrity": "sha512-RI4LFAraGrimMTxXkediCMXGVLC6ksXIIo3U+d3E4n+Mhw3uIDbmokO7DHlPB/eu6Tn6KBv4IUE1WrrEDRdNUQ==", - "dev": true - }, - "@types/js-yaml": { - "version": "3.12.7", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.7.tgz", - "integrity": "sha512-S6+8JAYTE1qdsc9HMVsfY7+SgSuUU/Tp6TYTmITW0PZxiyIMvol3Gy//y69Wkhs0ti4py5qgR3uZH6uz/DNzJQ==", - "dev": true - }, - "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true - }, - "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==", - "dev": true - }, - "@types/mocha": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.0.0.tgz", - "integrity": "sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==", - "dev": true - }, - "@types/node": { - "version": "16.11.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.4.tgz", - "integrity": "sha512-TMgXmy0v2xWyuCSCJM6NCna2snndD8yvQF67J29ipdzMcsPa9u+o0tjF5+EQNdhcuZplYuouYqpc4zcd5I6amQ==", - "dev": true - }, - "@types/promise.prototype.finally": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/promise.prototype.finally/-/promise.prototype.finally-2.0.4.tgz", - "integrity": "sha512-bkzsMz11tGI5r/ZhJIVI1+QSWKKBcX/Llv0zoM2ufOH+o/3sLXwE5xCW0OUX81xPa4EGOyPKFlNrH9GH+IF4lg==", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.2.0.tgz", - "integrity": "sha512-qQwg7sqYkBF4CIQSyRQyqsYvP+g/J0To9ZPVNJpfxfekl5RmdvQnFFTVVwpRtaUDFNvjfe/34TgY/dpc3MgNTw==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "5.2.0", - "@typescript-eslint/scope-manager": "5.2.0", - "debug": "^4.3.2", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.2.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.2.0.tgz", - "integrity": "sha512-RW+wowZqPzQw8MUFltfKYZfKXqA2qgyi6oi/31J1zfXJRpOn6tCaZtd9b5u9ubnDG2n/EMvQLeZrsLNPpaUiFQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.2.0", - "@typescript-eslint/visitor-keys": "5.2.0" - } - }, - "@typescript-eslint/types": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.2.0.tgz", - "integrity": "sha512-cTk6x08qqosps6sPyP2j7NxyFPlCNsJwSDasqPNjEQ8JMD5xxj2NHxcLin5AJQ8pAVwpQ8BMI3bTxR0zxmK9qQ==", - "dev": true - }, - "@typescript-eslint/visitor-keys": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.2.0.tgz", - "integrity": "sha512-Nk7HizaXWWCUBfLA/rPNKMzXzWS8Wg9qHMuGtT+v2/YpPij4nVXrVJc24N/r5WrrmqK31jCrZxeHqIgqRzs0Xg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.2.0", - "eslint-visitor-keys": "^3.0.0" - } - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - } - } - }, - "@typescript-eslint/experimental-utils": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.2.0.tgz", - "integrity": "sha512-fWyT3Agf7n7HuZZRpvUYdFYbPk3iDCq6fgu3ulia4c7yxmPnwVBovdSOX7RL+k8u6hLbrXcdAehlWUVpGh6IEw==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.2.0", - "@typescript-eslint/types": "5.2.0", - "@typescript-eslint/typescript-estree": "5.2.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.2.0.tgz", - "integrity": "sha512-RW+wowZqPzQw8MUFltfKYZfKXqA2qgyi6oi/31J1zfXJRpOn6tCaZtd9b5u9ubnDG2n/EMvQLeZrsLNPpaUiFQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.2.0", - "@typescript-eslint/visitor-keys": "5.2.0" - } - }, - "@typescript-eslint/types": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.2.0.tgz", - "integrity": "sha512-cTk6x08qqosps6sPyP2j7NxyFPlCNsJwSDasqPNjEQ8JMD5xxj2NHxcLin5AJQ8pAVwpQ8BMI3bTxR0zxmK9qQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.2.0.tgz", - "integrity": "sha512-RsdXq2XmVgKbm9nLsE3mjNUM7BTr/K4DYR9WfFVMUuozHWtH5gMpiNZmtrMG8GR385EOSQ3kC9HiEMJWimxd/g==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.2.0", - "@typescript-eslint/visitor-keys": "5.2.0", - "debug": "^4.3.2", - "globby": "^11.0.4", - "is-glob": "^4.0.3", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.2.0.tgz", - "integrity": "sha512-Nk7HizaXWWCUBfLA/rPNKMzXzWS8Wg9qHMuGtT+v2/YpPij4nVXrVJc24N/r5WrrmqK31jCrZxeHqIgqRzs0Xg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.2.0", - "eslint-visitor-keys": "^3.0.0" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - } - } - }, - "@typescript-eslint/parser": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.1.0.tgz", - "integrity": "sha512-vx1P+mhCtYw3+bRHmbalq/VKP2Y3gnzNgxGxfEWc6OFpuEL7iQdAeq11Ke3Rhy8NjgB+AHsIWEwni3e+Y7djKA==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.1.0", - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/typescript-estree": "5.1.0", - "debug": "^4.3.2" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.1.0.tgz", - "integrity": "sha512-yYlyVjvn5lvwCL37i4hPsa1s0ORsjkauhTqbb8MnpvUs7xykmcjGqwlNZ2Q5QpoqkJ1odlM2bqHqJwa28qV6Tw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/visitor-keys": "5.1.0" - } - }, - "@typescript-eslint/types": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.1.0.tgz", - "integrity": "sha512-sEwNINVxcB4ZgC6Fe6rUyMlvsB2jvVdgxjZEjQUQVlaSPMNamDOwO6/TB98kFt4sYYfNhdhTPBEQqNQZjMMswA==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.1.0.tgz", - "integrity": "sha512-SSz+l9YrIIsW4s0ZqaEfnjl156XQ4VRmJsbA0ZE1XkXrD3cRpzuZSVCyqeCMR3EBjF27IisWakbBDGhGNIOvfQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/visitor-keys": "5.1.0", - "debug": "^4.3.2", - "globby": "^11.0.4", - "is-glob": "^4.0.3", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.1.0.tgz", - "integrity": "sha512-uqNXepKBg81JVwjuqAxYrXa1Ql/YDzM+8g/pS+TCPxba0wZttl8m5DkrasbfnmJGHs4lQ2jTbcZ5azGhI7kK+w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.1.0", - "eslint-visitor-keys": "^3.0.0" - } - }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true - }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "dev": true - }, - "are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - }, - "dependencies": { - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - } - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true - }, - "ascli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", - "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", - "dev": true, - "requires": { - "colour": "~0.7.1", - "optjs": "~3.2.2" - } - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", - "dev": true - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=", - "dev": true - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "bytebuffer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", - "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", - "dev": true, - "requires": { - "long": "~3" - }, - "dependencies": { - "long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", - "dev": true - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, - "colour": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz", - "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "dev": true, - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.1.0.tgz", - "integrity": "sha512-JZvNneArGSUsluHWJ8g8MMs3CfIEzwaLx9KyH4tZ2i+R2/rPWzL8c0zg3rHdwYVpN/1sB9gqnjHwz9HoeJpGHw==", - "dev": true, - "requires": { - "@eslint/eslintrc": "^1.0.3", - "@humanwhocodes/config-array": "^0.6.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^6.0.0", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.0.0", - "espree": "^9.0.0", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.2.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - } - } - }, - "eslint-scope": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-6.0.0.tgz", - "integrity": "sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz", - "integrity": "sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q==", - "dev": true - }, - "espree": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.0.0.tgz", - "integrity": "sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ==", - "dev": true, - "requires": { - "acorn": "^8.5.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.0.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fast-text-encoding": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", - "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==", - "dev": true - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", - "dev": true - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "gauge": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.1.tgz", - "integrity": "sha512-6STz6KdQgxO4S/ko+AbjlFGGdGcknluoqU+79GOFCDqqyYj5OanQf9AjxwN0jCidtT+ziPMmPSt9E4hfQ0CwIQ==", - "dev": true, - "requires": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1 || ^2.0.0", - "strip-ansi": "^3.0.1 || ^4.0.0", - "wide-align": "^1.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "gaxios": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.2.tgz", - "integrity": "sha512-T+ap6GM6UZ0c4E6yb1y/hy2UB6hTrqhglp3XfmU9qbLCGRYhLVV5aRPpC4EmoG8N8zOnkYCgoBz+ScvGAARY6Q==", - "dev": true, - "requires": { - "abort-controller": "^3.0.0", - "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.1" - } - }, - "gcp-metadata": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.1.tgz", - "integrity": "sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==", - "dev": true, - "requires": { - "gaxios": "^4.0.0", - "json-bigint": "^1.0.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "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" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - } - } - }, - "google-auth-library": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.6.tgz", - "integrity": "sha512-Q+ZjUEvLQj/lrVHF/IQwRo6p3s8Nc44Zk/DALsN+ac3T4HY/g/3rrufkgtl+nZ1TW7DNAw5cTChdVp4apUXVgQ==", - "dev": true, - "requires": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - } - }, - "google-gax": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.28.0.tgz", - "integrity": "sha512-kuqc8a4+CTCMBcF3tlOL7Sa74JWkTzcZxatAQTCVK35WToXkHnJ0qncFOJuegUv3EbV9IQY4j/+NZdFLv+lbTA==", - "dev": true, - "requires": { - "@grpc/grpc-js": "~1.4.0", - "@grpc/proto-loader": "^0.6.1", - "@types/long": "^4.0.0", - "abort-controller": "^3.0.0", - "duplexify": "^4.0.0", - "fast-text-encoding": "^1.0.3", - "google-auth-library": "^7.6.1", - "is-stream-ended": "^0.1.4", - "node-fetch": "^2.6.1", - "object-hash": "^2.1.1", - "proto3-json-serializer": "^0.1.1", - "protobufjs": "6.11.2", - "retry-request": "^4.0.0" - }, - "dependencies": { - "google-auth-library": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.10.1.tgz", - "integrity": "sha512-nQxgM1ZopUMcpMnu95kOSzI+9tJl4YDOZJomSTBGlRLpxfBopdwto7WvzoI87HuN0nQqVETgOsHi/C/po1rppA==", - "dev": true, - "requires": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - } - } - } - }, - "google-p12-pem": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.2.tgz", - "integrity": "sha512-tjf3IQIt7tWCDsa0ofDQ1qqSCNzahXDxdAGJDbruWqu3eCg5CKLYKN+hi0s6lfvzYZ1GDVr+oDF9OOWlDSdf0A==", - "dev": true, - "requires": { - "node-forge": "^0.10.0" - } - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "grpc": { - "version": "1.24.11", - "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.24.11.tgz", - "integrity": "sha512-8/AQdFCzCeCDWW3SoaMNp6ccbRvTQEH1O1u1uFtt29eWsg5gSZCJ3m6fbkduEIh3smY7WAPP+LgVJ5n3nZRxcA==", - "dev": true, - "requires": { - "@mapbox/node-pre-gyp": "^1.0.4", - "@types/bytebuffer": "^5.0.40", - "lodash.camelcase": "^4.3.0", - "lodash.clone": "^4.5.0", - "nan": "^2.13.2", - "protobufjs": "^5.0.3" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "protobufjs": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz", - "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==", - "dev": true, - "requires": { - "ascli": "~1", - "bytebuffer": "~5", - "glob": "^7.0.5", - "yargs": "^3.10.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", - "dev": true, - "requires": { - "camelcase": "^2.0.1", - "cliui": "^3.0.3", - "decamelize": "^1.1.1", - "os-locale": "^1.4.0", - "string-width": "^1.0.1", - "window-size": "^0.1.4", - "y18n": "^3.2.0" - } - } - } - }, - "gtoken": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.3.1.tgz", - "integrity": "sha512-yqOREjzLHcbzz1UrQoxhBtpk8KjrVhuqPE7od1K2uhyxG2BHjKZetlbLw/SPZak/QqTIQW+addS+EcjqQsZbwQ==", - "dev": true, - "requires": { - "gaxios": "^4.0.0", - "google-p12-pem": "^3.0.3", - "jws": "^4.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "i18n": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/i18n/-/i18n-0.8.6.tgz", - "integrity": "sha512-aMsJq8i1XXrb+BBsgmJBwak9mr69zPEIAUPb6c5yw2G/O4k1Q52lBxL+agZdQDN/RGf1ylQzrCswsOOgIiC1FA==", - "dev": true, - "requires": { - "debug": "*", - "make-plural": "^6.0.1", - "math-interval-parser": "^2.0.1", - "messageformat": "^2.3.0", - "mustache": "*", - "sprintf-js": "^1.1.2" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "is-stream-ended": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", - "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==", - "dev": true - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "is-weakref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "dev": true, - "requires": { - "bignumber.js": "^9.0.0" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "dev": true, - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "dev": true, - "requires": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", - "dev": true - }, - "lodash.clone": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", - "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "make-plural": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-6.2.2.tgz", - "integrity": "sha512-8iTuFioatnTTmb/YJjywkVIHLjcwkFD9Ms0JpxjEm9Mo8eQYkh1z+55dwv4yc1jQ8ftVBxWQbihvZL1DfzGGWA==", - "dev": true - }, - "math-interval-parser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/math-interval-parser/-/math-interval-parser-2.0.1.tgz", - "integrity": "sha512-VmlAmb0UJwlvMyx8iPhXUDnVW1F9IrGEd9CIOmv+XL8AErCUUuozoDMrgImvnYt2A+53qVX/tPW6YJurMKYsvA==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "messageformat": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/messageformat/-/messageformat-2.3.0.tgz", - "integrity": "sha512-uTzvsv0lTeQxYI2y1NPa1lItL5VRI8Gb93Y2K2ue5gBPyrbJxfDi/EYWxh2PKv5yO42AJeeqblS9MJSh/IEk4w==", - "dev": true, - "requires": { - "make-plural": "^4.3.0", - "messageformat-formatters": "^2.0.1", - "messageformat-parser": "^4.1.2" - }, - "dependencies": { - "make-plural": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz", - "integrity": "sha512-xTYd4JVHpSCW+aqDof6w/MebaMVNTVYBZhbB/vi513xXdiPT92JMVCo0Jq8W2UZnzYRFeVbQiQ+I25l13JuKvA==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - } - } - }, - "messageformat-formatters": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/messageformat-formatters/-/messageformat-formatters-2.0.1.tgz", - "integrity": "sha512-E/lQRXhtHwGuiQjI7qxkLp8AHbMD5r2217XNe/SREbBlSawe0lOqsFb7rflZJmlQFSULNLIqlcjjsCPlB3m3Mg==", - "dev": true - }, - "messageformat-parser": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-4.1.3.tgz", - "integrity": "sha512-2fU3XDCanRqeOCkn7R5zW5VQHWf+T3hH65SzuqRvjatBK7r4uyFa5mEX+k6F9Bd04LVM5G4/BHBTUJsOdW7uyg==", - "dev": true - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "minipass": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", - "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "mocha": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz", - "integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==", - "dev": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.2", - "debug": "4.3.2", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.7", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "nanoid": "3.1.25", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.1.5", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "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-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "mustache": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", - "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", - "dev": true - }, - "nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "dev": true - }, - "nanoid": { - "version": "3.1.25", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", - "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node-fetch": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", - "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", - "dev": true - }, - "nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "dev": true, - "requires": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", - "dev": true - }, - "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "optjs": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", - "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=", - "dev": true - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "promise.prototype.finally": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/promise.prototype.finally/-/promise.prototype.finally-3.1.3.tgz", - "integrity": "sha512-EXRF3fC9/0gz4qkt/f5EP5iW4kj9oFpBICNpCNOb/52+8nlHIX07FPLbi/q4qYBQ1xZqivMzTpNQSnArVASolQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "proto3-json-serializer": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-0.1.4.tgz", - "integrity": "sha512-bFzdsKU/zaTobWrRxRniMZIzzcgKYlmBWL1gAcTXZ2M7TQTGPI0JoYYs6bN7tpWj59ZCfwg7Ii/A2e8BbQGYnQ==", - "dev": true - }, - "protobufjs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", - "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", - "dev": true, - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "retry-request": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.2.2.tgz", - "integrity": "sha512-xA93uxUD/rogV7BV59agW/JHPGXeREMWiZc9jhcwY4YdZ7QOtC7qbomYg0n4wyk2lJhggjvKvhNX8wln/Aldhg==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "extend": "^3.0.2" - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "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 - }, - "source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true - }, - "ts-node": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", - "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "0.7.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "yn": "3.1.1" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - } - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dev": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", - "dev": true - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "workerpool": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", - "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "dependencies": { - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - } - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } - } -} diff --git a/test/prod/package.json b/test/prod/package.json deleted file mode 100644 index f55c007a..00000000 --- a/test/prod/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "lis-mon-livre-test", - "version": "1.0.0", - "description": "", - "private": true, - "scripts": { - "lint": "eslint \"test/*.ts\"", - "enable-activity-controls": "env GOOGLE_APPLICATION_CREDENTIALS=$PWD/service_account.json web-and-app-activity-controls", - "test": "npm run lint && env GOOGLE_APPLICATION_CREDENTIALS=$PWD/service_account.json PROJECT_ID=$(cat $PWD/service_account.json| jq -r '.project_id') mocha --recursive --require ts-node/register test/*.ts" - }, - "author": "", - "license": "ISC", - "devDependencies": { - "@assistant/conversation-testing": "^1.0.0", - "@types/mocha": "^9.0.0", - "@types/node": "^16.11.4", - "@typescript-eslint/eslint-plugin": "^5.2.0", - "@typescript-eslint/parser": "^5.1.0", - "chai": "^4.3.4", - "eslint": "^8.1.0", - "mocha": "^9.1.3", - "ts-node": "^10.4.0", - "typescript": "^4.4.4" - } -} diff --git a/test/prod/test/test1.ts b/test/prod/test/test1.ts deleted file mode 100644 index 775959f1..00000000 --- a/test/prod/test/test1.ts +++ /dev/null @@ -1,56 +0,0 @@ -import 'mocha'; - -import {env} from 'process'; -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; - -const DEFAULT_LOCALE = 'fr-FR'; -const DEFAULT_SURFACE = 'PHONE'; -const CONTINUE_CONVO_PROMPT = "Bienvenue dans l'application d'écoute de livre audio valentin hauy Que voulez-vous faire ? Vous pouvez dire informations ou espace membres"; - -const PROJECT_ID = env['PROJECT_ID'] || ''; -const TRIGGER_PHRASE = 'Parler avec valentin audio'; - -console.log(`PROJECT_ID=${PROJECT_ID}`); - -ok(PROJECT_ID, 'no PROJECT_ID'); - -// tslint:disable:only-arrow-functions - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(CONTINUE_CONVO_PROMPT); - test.assertText(CONTINUE_CONVO_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_lvl1'); - - await test.sendQuery("espace membres"); - test.assertText("Pour continuer d'utiliser valentin audio, je dois associer votre compte valentin audio à Google. Êtes-vous d'accord ?"); - - await test.sendQuery("oui"); - test.assertText(""); - - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('trigger only', async () => { - await startConversation(); - // test.assertConversationEnded(); - }); -}); From 6c43177f26efbc9c3f53fc0463e2bd2bc1fc2e54 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 31 Jan 2022 15:53:58 +0100 Subject: [PATCH 084/180] fix: webhook actions --- .github/workflows/webhooks-test.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/webhooks-test.yml b/.github/workflows/webhooks-test.yml index 2f1dff2e..e1bc0747 100644 --- a/.github/workflows/webhooks-test.yml +++ b/.github/workflows/webhooks-test.yml @@ -3,10 +3,13 @@ name: webhooks unitary tests on: push: - branches: [ develop, mainp ] - # paths: + branches: [ develop, avh-dev ] + paths: + - 'webhooks/**' pull_request: - branches: [ develop, main ] + branches: [ develop, avh-dev ] + paths: + - 'webhooks/**' jobs: sdk-test-prod: From a73bd8441271fd5834545d1a05f326d3aab6b772 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 1 Feb 2022 15:31:51 +0100 Subject: [PATCH 085/180] flowchart --- flowchart.drawio | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flowchart.drawio b/flowchart.drawio index 2c9fe9ff..8af25367 100644 --- a/flowchart.drawio +++ b/flowchart.drawio @@ -1 +1 @@ -7VlLc9s2EP4tPWimPUgjknrlaMt2mtZN3XE7iU8ZiARJ2BDAAqAe+fXdBcGXSLl2Gj/SyYUkdrEAuPh2vwU5CJbr3VtFsvQ3GVE+8MfRbhCcDXzfezMdww0leyeZzeaFJFEscrJacM0+Uyd0hknOIqpbHY2U3LCsLQylEDQ0LRlRSm7b3WLJ27NmJKEdwXVIeFf6gUUmLaQLf17Lf6YsScuZvdmbQrMmZWf3Jjolkdw2RMH5IFgqKU3xtN4tKUfvlX4p7C6OaKuFKSrMQwzixe/6U3zzcXzyx+17IfNf1NXt0I2yITx3LzzwZxzGO9UZEfCc4HMpg8H7xF/Y9QPloVxTu6MDXPx4L3MFt+X55QncLtlKEbX/weoK85U6HLCW/ImDxDnne7hTcSv39Ygkj5hcSXmnsSEivIYh1bruklGlpSDoMU05QIlJWOmy6ADXLbPeFJRG5Yo5E3edVcO4Mhdm1F3gB5nzqBqPs7vq1SO8aLwIRMjFUSdaHJl9CU4FM0UU99cD9TZlhl5nJETtFuIRZKlZc6dOSZjmir5F+dkEBJlkwlB1vgEAYZSMqyk2VBm6O4ozr0IvxD2FLTQKfe0MJg7vLuKDmWtv6/AJyuhOm6ETOCFxIZtUQ9eohgcH7EeAfNpxHI0gyF1TSAG30zBXm8qVtWPRKVKZVCYIjkspM9fllhqzd/mK5LCNLWfTHTMf0Xw0da2bhuZs50a2jX3ZEPCyDSNs3jR1tZlt1XbRCWY6aMqMCowyQ5Rxa/MmRZdmUwNiQ3pFFQMHU4WYYSIB7QKUYJtQc0RZeBLddz86EM44xz274rtsbqe7p9+kH22KcmLYpr2Orw4dv5Mfr9G3HUBBcs/wERxBOKdcJoqsMcZKNx7qrmrFvwVuzHa02r5nDORg3o7kRTeQPb8nkGdPFcfBqyCrFQnvysT9CMJaSgH7bnJErRQaO91YIkjJBofVORJSyV9ILTRqEFjBKhV7hbgyyxYNJiPWhTKuzWKykQrAhctG9vvhMaykKVFhaosmuwQUZTRkMQvdeDhbQa+QIFXBlkhnTIcSoIdquwwDWdMfB4g+FloOtmbb1tSZorG1sdkLU04xp5soVnJdv5h9m5Ty+Ftny+n0gC6nL06XixekywZZ1tT5nS5LGnwAXR6B24Pp0pqCg8i+0cGCXzdGvkJBjWI46LVQXHJADcNixBqU1dK+HKfepMMHf72/fPf+1/OzXgRfkhWcTlu4I5wlgICzkIqCijGWGZz+TpxizaIIxzhVVLPPZGXHG5fpwHpnejqYnt2XDNzR1BnXB8ImCo4H4tHMMR5NFnO/7XbHkI/b7Ho3yy4yjjU1nUTyNfZs3Ls1z5JcvO/J5b8ml+Alksts0aZIfz59huTSLTb/T6nFG/fvZJVbxovFvOX1oTd/7cmlywfvoBaekTXWdmKls0ZtnwatXZz9neN3uNM1RACD3cFyfpzt4Dr0i7u1BcdGkY3AuoPTe81uK6kiqoYraQxUrbazTW2lPpQcKmArV8nqx2BiC2csn1uPP1UGsRRmGJM1g9OBNavea+AHgc0jNJE4Qc46qmpETYQeasgmcf3GZblcnTAK/2zrE8IlnEVsOd7RwFnY5LpRf6NXj1XfqVyvoPOrqbyDg8ob9rN7vp31Vd7Tp6q8veOfY/EklMIJqYXW1Bj8DH6Cs/oXxH6z1EMphomUCaejhJk0X42YRK3WDLgIYARJAxyn7Tl0KGREb2ELL4LRfATvdRFy6ElR0uz3KYVzJ6fqUw7wGdmL3TI/cLjhBUh0iYgDdL3ilZbYJUehCxgzbYxqo+QdXRZRXFYtMeP8QPRwEugLinbl82zfbw/o1vO6cTHpjYv5k8XFtCcuXnt+8abtM9F03vXjoseNiyfz4qzjxT3V3XqGc5bpY5h8AUcOq5+BzpOznl8KfZ58OjzOO54U8htw5Jtn8yM06z+bRX1X/yAOzv8B \ No newline at end of file +7VlLc9s2EP4tOWimPUgjkqIkH23ZTtO6qTtuJ/EpA5EgCRsCWAC0pPz67ILgS5TcOGM7yrQXkthdLMDdbx8gB8FitXmrSJ79LmPKB/443gyC84Hv+8HEhxtStiUl8KdhSUkVi0ua1xBu2GfqiGNHLVhMdUfQSMkNy7vESApBI9OhEaXkuiuWSN5dNScp7RFuIsL71A8sNllJnfuzhv4LZWlWrexNT0rOilTC7k10RmK5bpGCi0GwUFKa8mm1WVCO1qvsUs67PMCtN6aoMF8zIZn/oT8ltx/Hp3/evRey+FVd3w2dlgfCC/fCA3/KQd+ZzomA5xSfKxoo30f+RtEPlEdyRa1HB7j58VYWCm6Li6tTuF2xpSJq+8byyulLtauwofyFSpKC8y3cqbiT20YjKWIml1LeaxyIGK9RRLVuRHKqtBQELaYpBygxCTtdlAJwXTNrTUFpXO2YM3Hf2zXolYUwo/4GP8iCx7U+zu7rV4/xovEiECGXB41ocWS2FTgVrBRT9K8H7HXGDL3JSYTcNcQj0DKz4o6dkSgrFH2L9PMJEHLJhKHq4gEAhFEyrpdog6pCCFWGblokB7K3FFxoFNracScO71XET9143YRPUEV31g6dwBGJC9m0Vt2gGh4csJ8A8rBnOBpDkLuhkAJuZ1GhHmpTNoZFo0hlMpkiOK6kzJ3IHTVm6/IVKcCNHWPTDTMfcfoodKPbFud84zTbwbYaCHjZ1iQc3rZ5zTQ7aubFp5jpYChzKjDKDFHG7c2blCLtoQbERvSaKgYGpgoxw0QK3DkwYW5KzQHmQXyUKh9xgisEpfZH5CalHHroUbQpyolhD900/ezQ8Xv58QZt2wMUJPccH8EyhHPKZarICmOsMuMu77ph/FvgJmxDa/e9YiAHs24kz/uB7Pl7Ann6UnEcHEWxWpLovkrcTyhYCynA76ZA1EqhUejWFoKMPKBaXWBBquoXlhYatwpYWVXq6hXhzmy1aFUyYk0ok2ZaQh6kAnDhtrH6vXlKVdKUqCizTZPdApJyGrGERU4frlaWV0iQqqyWWM6YjiTgDNl2Gwaypj8OEJAssjXYTlt3ls4VTewcm70w5ZRruoUSJVfNi9m3yShPfvRqGYY75TL87uVy/h3LZatYNqXzv1guJ19ZLr3nLpd2KhiIbFsCFvy6pfkaCQ2KvZOwg+KqBjQwLDU2oKy39u049Sa9evD3+6t373+7ON+L4CuyhNNpB3eEsxQQcB5RUZZiDFwGp79Tx1ixOEYdZ4pq9pksrb5xlQ6sdcKzQXi+19ePRVcvQ9RHWLdI55S4L3OMR5P5zO+a3VXIpzm78WYlIpNEU9NLJM/hs/Fe17xKcvH+Ty5PTC7BUSSX6bxbIv1Z+ArJpd9sHn1qqYLrOXLLeD6fdaw+9GbHnlz69eAd9MJTssLeTix13urts6Djxek/BX6HO1tBSDDwDrbz43wD16Ff3u1c8EEc2whsBBzfa4stpYqpGi6lMdC1WmGb2ip+JDl0wJau0uVPwcQ2ztg+dx5/rickUphhQlYMTgd2Wv1eAz8IbB6hqcQFCtZj1Ro1EXqoIZskzRtX7XJ9wijts25OCFdwFrHteI8DZ2FT6Fb/jVY91H1ncrUE4aPpvIOdzhv82T/fTvd13uFLdd7e4c+xeBLK4ITUQWtmDH4GP8VV/Utiv1nqoRTDVMqU01HKTFYsR0wiV2sGtQhgBLkArKTtOXQoZEzvwIWXwWg2gve6jDhIUqS05T5lcO7kVH0qAD4je7Eu8wOHG16CRFeI2EHXEe+0wi45CF0AlOliVBsl7+mijOKqa0kY5zukry8C+4Ki2/m82vfbnXLref24mOyNi9mLxUW4Jy6OPb94YfdMFM76dpzvMeP8xaw47VlxS3W/n+Gc5foQJr+DIYf1z0BnyemeXwr7LPlyeJz1LCnkD2DIk1ezIwybP5tlf9f8IA4uvgA= \ No newline at end of file From c7a4b234068afe5bb83072bc2d48ef900eb92333 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 1 Feb 2022 23:01:52 +0100 Subject: [PATCH 086/180] first clean --- sdk/actions/actions.yaml | 1 - sdk/custom/global/actions.intent.CANCEL.yaml | 9 - sdk/custom/global/actions.intent.MAIN.yaml | 2 - .../actions.intent.MEDIA_STATUS_STOPPED.yaml | 1 - .../global/actions.intent.NO_INPUT_1.yaml | 7 - .../global/actions.intent.NO_INPUT_2.yaml | 7 - .../global/actions.intent.NO_INPUT_FINAL.yaml | 8 - .../global/actions.intent.NO_MATCH_1.yaml | 7 - .../global/actions.intent.NO_MATCH_2.yaml | 7 - .../global/actions.intent.NO_MATCH_FINAL.yaml | 8 - .../intents/enter_member_space_lvl1.yaml | 5 - .../intents/get_info_association_lvl1.yaml | 4 - sdk/custom/intents/i_want_to_listen_lvl3.yaml | 10 - sdk/custom/intents/listen_audiobook_lvl1.yaml | 6 - sdk/custom/intents/listen_audiobook_lvl2.yaml | 12 - sdk/custom/intents/listen_toc.yaml | 5 - sdk/custom/intents/menu.yaml | 3 - sdk/custom/intents/next.yaml | 2 - sdk/custom/intents/no.yaml | 5 - sdk/custom/intents/remaing_time_player.yaml | 7 - sdk/custom/intents/repeat.yaml | 2 - sdk/custom/intents/resume_audiobook_lvl2.yaml | 11 - .../intents/resume_listening_player.yaml | 5 - .../selection_all_publication_lvl3.yaml | 2 - .../intents/selection_audiobook_lvl2.yaml | 5 - sdk/custom/intents/selection_genre_lvl3.yaml | 4 - .../intents/selection_my_list_lvl3.yaml | 4 - .../intents/selection_thematic_list_lvl3.yaml | 4 - sdk/custom/intents/stop.yaml | 3 - sdk/custom/intents/test_player_sdk.yaml | 7 - sdk/custom/intents/test_setup_sdk.yaml | 8 - sdk/custom/intents/test_webhook.yaml | 3 - sdk/custom/intents/yes.yaml | 6 - ...sk_to_resume_listening_at_last_offset.yaml | 9 - sdk/custom/scenes/home_lvl1.yaml | 18 - .../scenes/home_lvl1_AccountLinking.yaml | 19 - sdk/custom/scenes/home_members_lvl2.yaml | 30 - sdk/custom/scenes/player.yaml | 27 - sdk/custom/scenes/player_toc.yaml | 19 - sdk/custom/scenes/search.yaml | 13 - sdk/custom/scenes/select_group.yaml | 64 -- sdk/custom/scenes/select_publication.yaml | 74 -- sdk/custom/scenes/selection_lvl3.yaml | 15 - sdk/custom/types/string.yaml | 1 - webhooks/functions/package-lock.json | 69 ++ webhooks/functions/package.json | 7 +- webhooks/functions/src/constants.ts | 2 + webhooks/functions/src/conversation/test.ts | 51 -- webhooks/functions/src/index.ts | 797 +----------------- .../src/{ => model}/database/firestore.ts | 0 .../src/{ => model}/database/index.ts | 0 webhooks/functions/src/model/storage.model.ts | 51 ++ webhooks/functions/src/model/storage.test.ts | 12 + webhooks/functions/src/sdk.d.ts | 4 - webhooks/functions/src/service/listGroups.ts | 30 - .../functions/src/service/listPublication.ts | 45 - webhooks/functions/src/service/persist.ts | 27 - .../functions/src/service/selectGroups.ts | 21 - .../src/service/selectPublication.ts | 26 - webhooks/functions/src/type.ts | 35 +- webhooks/functions/src/utils/index.ts | 85 -- 61 files changed, 156 insertions(+), 1575 deletions(-) delete mode 100644 sdk/custom/global/actions.intent.CANCEL.yaml delete mode 100644 sdk/custom/global/actions.intent.MAIN.yaml delete mode 100644 sdk/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml delete mode 100644 sdk/custom/global/actions.intent.NO_INPUT_1.yaml delete mode 100644 sdk/custom/global/actions.intent.NO_INPUT_2.yaml delete mode 100644 sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml delete mode 100644 sdk/custom/global/actions.intent.NO_MATCH_1.yaml delete mode 100644 sdk/custom/global/actions.intent.NO_MATCH_2.yaml delete mode 100644 sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml delete mode 100644 sdk/custom/intents/enter_member_space_lvl1.yaml delete mode 100644 sdk/custom/intents/get_info_association_lvl1.yaml delete mode 100644 sdk/custom/intents/i_want_to_listen_lvl3.yaml delete mode 100644 sdk/custom/intents/listen_audiobook_lvl1.yaml delete mode 100644 sdk/custom/intents/listen_audiobook_lvl2.yaml delete mode 100644 sdk/custom/intents/listen_toc.yaml delete mode 100644 sdk/custom/intents/menu.yaml delete mode 100644 sdk/custom/intents/next.yaml delete mode 100644 sdk/custom/intents/no.yaml delete mode 100644 sdk/custom/intents/remaing_time_player.yaml delete mode 100644 sdk/custom/intents/repeat.yaml delete mode 100644 sdk/custom/intents/resume_audiobook_lvl2.yaml delete mode 100644 sdk/custom/intents/resume_listening_player.yaml delete mode 100644 sdk/custom/intents/selection_all_publication_lvl3.yaml delete mode 100644 sdk/custom/intents/selection_audiobook_lvl2.yaml delete mode 100644 sdk/custom/intents/selection_genre_lvl3.yaml delete mode 100644 sdk/custom/intents/selection_my_list_lvl3.yaml delete mode 100644 sdk/custom/intents/selection_thematic_list_lvl3.yaml delete mode 100644 sdk/custom/intents/stop.yaml delete mode 100644 sdk/custom/intents/test_player_sdk.yaml delete mode 100644 sdk/custom/intents/test_setup_sdk.yaml delete mode 100644 sdk/custom/intents/test_webhook.yaml delete mode 100644 sdk/custom/intents/yes.yaml delete mode 100644 sdk/custom/scenes/ask_to_resume_listening_at_last_offset.yaml delete mode 100644 sdk/custom/scenes/home_lvl1.yaml delete mode 100644 sdk/custom/scenes/home_lvl1_AccountLinking.yaml delete mode 100644 sdk/custom/scenes/home_members_lvl2.yaml delete mode 100644 sdk/custom/scenes/player.yaml delete mode 100644 sdk/custom/scenes/player_toc.yaml delete mode 100644 sdk/custom/scenes/search.yaml delete mode 100644 sdk/custom/scenes/select_group.yaml delete mode 100644 sdk/custom/scenes/select_publication.yaml delete mode 100644 sdk/custom/scenes/selection_lvl3.yaml delete mode 100644 sdk/custom/types/string.yaml delete mode 100644 webhooks/functions/src/conversation/test.ts rename webhooks/functions/src/{ => model}/database/firestore.ts (100%) rename webhooks/functions/src/{ => model}/database/index.ts (100%) create mode 100644 webhooks/functions/src/model/storage.model.ts delete mode 100644 webhooks/functions/src/sdk.d.ts delete mode 100644 webhooks/functions/src/service/listGroups.ts delete mode 100644 webhooks/functions/src/service/listPublication.ts delete mode 100644 webhooks/functions/src/service/persist.ts delete mode 100644 webhooks/functions/src/service/selectGroups.ts delete mode 100644 webhooks/functions/src/service/selectPublication.ts delete mode 100644 webhooks/functions/src/utils/index.ts diff --git a/sdk/actions/actions.yaml b/sdk/actions/actions.yaml index 96f74818..f82f9c46 100644 --- a/sdk/actions/actions.yaml +++ b/sdk/actions/actions.yaml @@ -1,3 +1,2 @@ custom: actions.intent.MAIN: {} - actions.intent.MEDIA_STATUS_STOPPED: {} diff --git a/sdk/custom/global/actions.intent.CANCEL.yaml b/sdk/custom/global/actions.intent.CANCEL.yaml deleted file mode 100644 index 22c095fb..00000000 --- a/sdk/custom/global/actions.intent.CANCEL.yaml +++ /dev/null @@ -1,9 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Au revoir et a bientôt - webhookHandler: cancel -transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/custom/global/actions.intent.MAIN.yaml b/sdk/custom/global/actions.intent.MAIN.yaml deleted file mode 100644 index c43ab2e2..00000000 --- a/sdk/custom/global/actions.intent.MAIN.yaml +++ /dev/null @@ -1,2 +0,0 @@ -handler: - webhookHandler: main diff --git a/sdk/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml b/sdk/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml deleted file mode 100644 index af0c87f2..00000000 --- a/sdk/custom/global/actions.intent.MEDIA_STATUS_STOPPED.yaml +++ /dev/null @@ -1 +0,0 @@ -transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/custom/global/actions.intent.NO_INPUT_1.yaml b/sdk/custom/global/actions.intent.NO_INPUT_1.yaml deleted file mode 100644 index de975f82..00000000 --- a/sdk/custom/global/actions.intent.NO_INPUT_1.yaml +++ /dev/null @@ -1,7 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n'ai pas entendu. Que voulez-vous dire ? diff --git a/sdk/custom/global/actions.intent.NO_INPUT_2.yaml b/sdk/custom/global/actions.intent.NO_INPUT_2.yaml deleted file mode 100644 index 59e57245..00000000 --- a/sdk/custom/global/actions.intent.NO_INPUT_2.yaml +++ /dev/null @@ -1,7 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Que dite-vous ? diff --git a/sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml b/sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml deleted file mode 100644 index 63087279..00000000 --- a/sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml +++ /dev/null @@ -1,8 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Je quitte l'application -transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/custom/global/actions.intent.NO_MATCH_1.yaml b/sdk/custom/global/actions.intent.NO_MATCH_1.yaml deleted file mode 100644 index 166efc70..00000000 --- a/sdk/custom/global/actions.intent.NO_MATCH_1.yaml +++ /dev/null @@ -1,7 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n'ai pas compris. Que voulez-vous dire ? diff --git a/sdk/custom/global/actions.intent.NO_MATCH_2.yaml b/sdk/custom/global/actions.intent.NO_MATCH_2.yaml deleted file mode 100644 index deda0dc7..00000000 --- a/sdk/custom/global/actions.intent.NO_MATCH_2.yaml +++ /dev/null @@ -1,7 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n'ai vraiment pas compris. Que voulez-vous dire ? diff --git a/sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml b/sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml deleted file mode 100644 index 2f8cf92a..00000000 --- a/sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml +++ /dev/null @@ -1,8 +0,0 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: malheureusement je m'en vais, je ne comprend pas -transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/custom/intents/enter_member_space_lvl1.yaml b/sdk/custom/intents/enter_member_space_lvl1.yaml deleted file mode 100644 index b61cfd70..00000000 --- a/sdk/custom/intents/enter_member_space_lvl1.yaml +++ /dev/null @@ -1,5 +0,0 @@ -trainingPhrases: -- espace maman -- membres -- espace membres -- Je veux entrer dans l'espace membres diff --git a/sdk/custom/intents/get_info_association_lvl1.yaml b/sdk/custom/intents/get_info_association_lvl1.yaml deleted file mode 100644 index 837e0830..00000000 --- a/sdk/custom/intents/get_info_association_lvl1.yaml +++ /dev/null @@ -1,4 +0,0 @@ -trainingPhrases: -- informations -- obtenir des informations -- Je veux obtenir des informations sur l'association diff --git a/sdk/custom/intents/i_want_to_listen_lvl3.yaml b/sdk/custom/intents/i_want_to_listen_lvl3.yaml deleted file mode 100644 index aa4c1c81..00000000 --- a/sdk/custom/intents/i_want_to_listen_lvl3.yaml +++ /dev/null @@ -1,10 +0,0 @@ -parameters: -- name: query - type: - name: string -trainingPhrases: -- ($query 'le nom du livre suivi de l\'auteur' auto=false) -- je veux écouter ($query 'cyrano de Bergerac d\'Edmond Rostand' auto=false) -- je veux écouter ($query 'le rouge et le noir de stendhall' auto=false) -- je veux écouter ($query 'le rouge et le noir' auto=false) -- je veux écouter ($query 'la chartreuse de parme' auto=false) diff --git a/sdk/custom/intents/listen_audiobook_lvl1.yaml b/sdk/custom/intents/listen_audiobook_lvl1.yaml deleted file mode 100644 index 5ee4919f..00000000 --- a/sdk/custom/intents/listen_audiobook_lvl1.yaml +++ /dev/null @@ -1,6 +0,0 @@ -trainingPhrases: -- recherche d'un livre -- recherche -- rechercher ($number1 'un' auto=true) livre -- écouter un livre -- je veux écouter un livre diff --git a/sdk/custom/intents/listen_audiobook_lvl2.yaml b/sdk/custom/intents/listen_audiobook_lvl2.yaml deleted file mode 100644 index 61fb43ec..00000000 --- a/sdk/custom/intents/listen_audiobook_lvl2.yaml +++ /dev/null @@ -1,12 +0,0 @@ -trainingPhrases: -- recherche d'un livre -- recherche -- rechercher ($number1 'un' auto=true) livre -- je veux écouter -- je veux écouter un livre -- écouter -- livre audio -- livre -- écouter u($number1 'n ' auto=true)audiobook -- écouter un livre -- écouter un livre audio diff --git a/sdk/custom/intents/listen_toc.yaml b/sdk/custom/intents/listen_toc.yaml deleted file mode 100644 index 68285400..00000000 --- a/sdk/custom/intents/listen_toc.yaml +++ /dev/null @@ -1,5 +0,0 @@ -trainingPhrases: -- table des matières -- lis la table des matières -- lis moi la table des matières -- lis moi la toc diff --git a/sdk/custom/intents/menu.yaml b/sdk/custom/intents/menu.yaml deleted file mode 100644 index fade5c08..00000000 --- a/sdk/custom/intents/menu.yaml +++ /dev/null @@ -1,3 +0,0 @@ -trainingPhrases: -- revenir au menu -- menu diff --git a/sdk/custom/intents/next.yaml b/sdk/custom/intents/next.yaml deleted file mode 100644 index 79a4e281..00000000 --- a/sdk/custom/intents/next.yaml +++ /dev/null @@ -1,2 +0,0 @@ -trainingPhrases: -- suivant diff --git a/sdk/custom/intents/no.yaml b/sdk/custom/intents/no.yaml deleted file mode 100644 index 873ac739..00000000 --- a/sdk/custom/intents/no.yaml +++ /dev/null @@ -1,5 +0,0 @@ -trainingPhrases: -- "n" -- non -- "no" -- nop diff --git a/sdk/custom/intents/remaing_time_player.yaml b/sdk/custom/intents/remaing_time_player.yaml deleted file mode 100644 index 703f8de9..00000000 --- a/sdk/custom/intents/remaing_time_player.yaml +++ /dev/null @@ -1,7 +0,0 @@ -trainingPhrases: -- combien de temps de lecture me restent-t-il ? -- depuis combien de temps j'écoute ce livre ? -- dis-moi le temps de lecture -- donne moi le temps de lecture -- quel temps me reste-t-il ? -- combien de temps de lecture reste-t-il ? diff --git a/sdk/custom/intents/repeat.yaml b/sdk/custom/intents/repeat.yaml deleted file mode 100644 index bc2af48e..00000000 --- a/sdk/custom/intents/repeat.yaml +++ /dev/null @@ -1,2 +0,0 @@ -trainingPhrases: -- répéter diff --git a/sdk/custom/intents/resume_audiobook_lvl2.yaml b/sdk/custom/intents/resume_audiobook_lvl2.yaml deleted file mode 100644 index 838b6349..00000000 --- a/sdk/custom/intents/resume_audiobook_lvl2.yaml +++ /dev/null @@ -1,11 +0,0 @@ -trainingPhrases: -- lecture d'($number1 'un' auto=true) livre -- lecture de mon livre -- lecture -- lis ($number1 'un' auto=true) livre -- lis mon livre -- reprend la lecture de mon dernier livre -- reprendre l'écoute -- reprendre la lecture de mon dernier livre -- reprend la lecture -- reprendre la lecture diff --git a/sdk/custom/intents/resume_listening_player.yaml b/sdk/custom/intents/resume_listening_player.yaml deleted file mode 100644 index d03ff0d7..00000000 --- a/sdk/custom/intents/resume_listening_player.yaml +++ /dev/null @@ -1,5 +0,0 @@ -trainingPhrases: -- continue -- reprends -- reprend la lecture -- reprendre la lecture diff --git a/sdk/custom/intents/selection_all_publication_lvl3.yaml b/sdk/custom/intents/selection_all_publication_lvl3.yaml deleted file mode 100644 index 97be19f7..00000000 --- a/sdk/custom/intents/selection_all_publication_lvl3.yaml +++ /dev/null @@ -1,2 +0,0 @@ -trainingPhrases: -- toute les publications diff --git a/sdk/custom/intents/selection_audiobook_lvl2.yaml b/sdk/custom/intents/selection_audiobook_lvl2.yaml deleted file mode 100644 index f07b780e..00000000 --- a/sdk/custom/intents/selection_audiobook_lvl2.yaml +++ /dev/null @@ -1,5 +0,0 @@ -trainingPhrases: -- ma liste de lecture -- liste de lecture -- selection d'($number1 'un' auto=true) livre -- selection diff --git a/sdk/custom/intents/selection_genre_lvl3.yaml b/sdk/custom/intents/selection_genre_lvl3.yaml deleted file mode 100644 index 63195424..00000000 --- a/sdk/custom/intents/selection_genre_lvl3.yaml +++ /dev/null @@ -1,4 +0,0 @@ -trainingPhrases: -- je veux la sélection par genre -- genre -- sélection par genre diff --git a/sdk/custom/intents/selection_my_list_lvl3.yaml b/sdk/custom/intents/selection_my_list_lvl3.yaml deleted file mode 100644 index 020db8d6..00000000 --- a/sdk/custom/intents/selection_my_list_lvl3.yaml +++ /dev/null @@ -1,4 +0,0 @@ -trainingPhrases: -- je veux ma liste -- ma liste de lecture -- ma liste diff --git a/sdk/custom/intents/selection_thematic_list_lvl3.yaml b/sdk/custom/intents/selection_thematic_list_lvl3.yaml deleted file mode 100644 index 5ff3b4b0..00000000 --- a/sdk/custom/intents/selection_thematic_list_lvl3.yaml +++ /dev/null @@ -1,4 +0,0 @@ -trainingPhrases: -- sélection thématique -- je veux la liste thématique -- liste thématique diff --git a/sdk/custom/intents/stop.yaml b/sdk/custom/intents/stop.yaml deleted file mode 100644 index 432c35ff..00000000 --- a/sdk/custom/intents/stop.yaml +++ /dev/null @@ -1,3 +0,0 @@ -trainingPhrases: -- revenir au menu précédent -- partir de là diff --git a/sdk/custom/intents/test_player_sdk.yaml b/sdk/custom/intents/test_player_sdk.yaml deleted file mode 100644 index 69b07339..00000000 --- a/sdk/custom/intents/test_player_sdk.yaml +++ /dev/null @@ -1,7 +0,0 @@ -parameters: -- name: number - type: - name: actions.type.Number -trainingPhrases: -- test player sdk ($number '123' auto=false) -- test player ($number '123' auto=true) diff --git a/sdk/custom/intents/test_setup_sdk.yaml b/sdk/custom/intents/test_setup_sdk.yaml deleted file mode 100644 index dd25c1d1..00000000 --- a/sdk/custom/intents/test_setup_sdk.yaml +++ /dev/null @@ -1,8 +0,0 @@ -parameters: -- name: number - type: - name: actions.type.Number -trainingPhrases: -- setup test ($number '123' auto=false) -- test setup sdk ($number '123' auto=true) -- setup test sdk ($number '123' auto=true) diff --git a/sdk/custom/intents/test_webhook.yaml b/sdk/custom/intents/test_webhook.yaml deleted file mode 100644 index b955a43c..00000000 --- a/sdk/custom/intents/test_webhook.yaml +++ /dev/null @@ -1,3 +0,0 @@ -trainingPhrases: -- test -- test webhook diff --git a/sdk/custom/intents/yes.yaml b/sdk/custom/intents/yes.yaml deleted file mode 100644 index 92072da0..00000000 --- a/sdk/custom/intents/yes.yaml +++ /dev/null @@ -1,6 +0,0 @@ -trainingPhrases: -- "y" -- ui -- ouep -- ouais -- oui diff --git a/sdk/custom/scenes/ask_to_resume_listening_at_last_offset.yaml b/sdk/custom/scenes/ask_to_resume_listening_at_last_offset.yaml deleted file mode 100644 index 84eb2ac0..00000000 --- a/sdk/custom/scenes/ask_to_resume_listening_at_last_offset.yaml +++ /dev/null @@ -1,9 +0,0 @@ -intentEvents: -- handler: - webhookHandler: ask_to_resume_listening_at_last_offset__intent__yes - intent: "yes" -- handler: - webhookHandler: ask_to_resume_listening_at_last_offset__intent__no - intent: "no" -onEnter: - webhookHandler: ask_to_resume_listening_at_last_offset diff --git a/sdk/custom/scenes/home_lvl1.yaml b/sdk/custom/scenes/home_lvl1.yaml deleted file mode 100644 index e9a83216..00000000 --- a/sdk/custom/scenes/home_lvl1.yaml +++ /dev/null @@ -1,18 +0,0 @@ -intentEvents: -- handler: - webhookHandler: home_lvl1__intent__get_info_association_lvl1 - intent: get_info_association_lvl1 -- handler: - webhookHandler: home_lvl1__intent__enter_member_space_lvl1 - intent: enter_member_space_lvl1 -- handler: - webhookHandler: home_lvl1__intent__resume_listening_player - intent: resume_listening_player -- handler: - webhookHandler: home_lvl1__intent__listen_audiobook_lvl1 - intent: listen_audiobook_lvl1 -- handler: - webhookHandler: test_webhook - intent: test_webhook -onEnter: - webhookHandler: home_lvl1 diff --git a/sdk/custom/scenes/home_lvl1_AccountLinking.yaml b/sdk/custom/scenes/home_lvl1_AccountLinking.yaml deleted file mode 100644 index a3fb2cf1..00000000 --- a/sdk/custom/scenes/home_lvl1_AccountLinking.yaml +++ /dev/null @@ -1,19 +0,0 @@ -conditionalEvents: -- condition: session.params.AccountLinkingSlot == "LINKED" - transitionToScene: home_members_lvl2 -- condition: session.params.AccountLinkingSlot == "ERROR" - transitionToScene: home_lvl1 -- condition: session.params.AccountLinkingSlot == "REJECTED" - transitionToScene: home_lvl1 -slots: -- commitBehavior: - writeSessionParam: AccountLinkingSlot - config: - '@type': type.googleapis.com/google.actions.conversation.v3.SignInSpec - opt_context: "" - defaultValue: - sessionParam: AccountLinkingSlot - name: AccountLinkingSlot - required: true - type: - name: actions.type.AccountLinking diff --git a/sdk/custom/scenes/home_members_lvl2.yaml b/sdk/custom/scenes/home_members_lvl2.yaml deleted file mode 100644 index b0d4ccf9..00000000 --- a/sdk/custom/scenes/home_members_lvl2.yaml +++ /dev/null @@ -1,30 +0,0 @@ -intentEvents: -- handler: - webhookHandler: home_members_lvl2__intent__listen_audiobook_lvl2 - intent: listen_audiobook_lvl2 -- handler: - webhookHandler: home_members_lvl2__intent__resume_audiobook_lvl2 - intent: resume_audiobook_lvl2 -- handler: - webhookHandler: home_members__intent__selection_audiobook_lvl2 - intent: selection_audiobook_lvl2 -- handler: - webhookHandler: test_setup_sdk - intent: test_setup_sdk - transitionToScene: home_members_lvl2 -- handler: - webhookHandler: test_player_sdk - intent: test_player_sdk - transitionToScene: home_members_lvl2 -- handler: - webhookHandler: test_webhook - intent: test_webhook -- intent: menu - transitionToScene: home_members_lvl2 -- handler: - webhookHandler: selection_lvl3__intent__selection_my_list_lvl3 - intent: selection_my_list_lvl3 -- intent: listen_toc - transitionToScene: player_toc -onEnter: - webhookHandler: home_members_lvl2 diff --git a/sdk/custom/scenes/player.yaml b/sdk/custom/scenes/player.yaml deleted file mode 100644 index 4f882dde..00000000 --- a/sdk/custom/scenes/player.yaml +++ /dev/null @@ -1,27 +0,0 @@ -intentEvents: -- handler: - webhookHandler: player__intent__resume_listening_player - intent: resume_listening_player -- handler: - webhookHandler: player__intent__remaining_time_player - intent: remaing_time_player -- handler: - webhookHandler: player__intent__listen_toc - intent: listen_toc -- handler: - webhookHandler: player__intent__menu - intent: menu -- handler: - webhookHandler: media_status - intent: actions.intent.MEDIA_STATUS_FINISHED -- handler: - webhookHandler: media_status - intent: actions.intent.MEDIA_STATUS_PAUSED -- handler: - webhookHandler: media_status - intent: actions.intent.MEDIA_STATUS_STOPPED -- handler: - webhookHandler: media_status - intent: actions.intent.MEDIA_STATUS_FAILED -onEnter: - webhookHandler: player diff --git a/sdk/custom/scenes/player_toc.yaml b/sdk/custom/scenes/player_toc.yaml deleted file mode 100644 index 7cfb9b62..00000000 --- a/sdk/custom/scenes/player_toc.yaml +++ /dev/null @@ -1,19 +0,0 @@ -intentEvents: -- handler: - webhookHandler: player_toc__intent__repeat - intent: repeat -- handler: - webhookHandler: player_toc__intent__next - intent: next -- handler: - webhookHandler: player_toc__intent__resume_listening_player - intent: resume_listening_player -onEnter: - webhookHandler: player_toc -onSlotUpdated: - webhookHandler: player_toc__slot__number -slots: -- name: number - required: true - type: - name: actions.type.Number diff --git a/sdk/custom/scenes/search.yaml b/sdk/custom/scenes/search.yaml deleted file mode 100644 index 7a750ecb..00000000 --- a/sdk/custom/scenes/search.yaml +++ /dev/null @@ -1,13 +0,0 @@ -intentEvents: -- handler: - webhookHandler: search__intent__resume_listening_player - intent: resume_listening_player -onEnter: - webhookHandler: search -onSlotUpdated: - webhookHandler: search__slot__query -slots: -- name: query - required: true - type: - name: string diff --git a/sdk/custom/scenes/select_group.yaml b/sdk/custom/scenes/select_group.yaml deleted file mode 100644 index 203b7eb2..00000000 --- a/sdk/custom/scenes/select_group.yaml +++ /dev/null @@ -1,64 +0,0 @@ -intentEvents: -- handler: - webhookHandler: select_group__intent__stop - intent: stop -- handler: - webhookHandler: select_group__intent__menu - intent: menu -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, merci de le répêter - intent: actions.intent.NO_MATCH_1 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, dite un numéro - intent: actions.intent.NO_MATCH_2 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, dite un numéro - intent: actions.intent.NO_MATCH_FINAL -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, dite un numéro - intent: actions.intent.NO_INPUT_1 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, dite un numéro - intent: actions.intent.NO_INPUT_2 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro - intent: actions.intent.NO_INPUT_FINAL -onEnter: - webhookHandler: select_group -onSlotUpdated: - webhookHandler: select_group__slot__number -slots: -- name: number - required: true - type: - name: actions.type.Number diff --git a/sdk/custom/scenes/select_publication.yaml b/sdk/custom/scenes/select_publication.yaml deleted file mode 100644 index d2cab1b4..00000000 --- a/sdk/custom/scenes/select_publication.yaml +++ /dev/null @@ -1,74 +0,0 @@ -intentEvents: -- handler: - webhookHandler: select_publication__intent__resume_listening_player - intent: resume_listening_player -- handler: - webhookHandler: select_publication__intent__stop - intent: stop -- handler: - webhookHandler: select_publication__intent__next - intent: next -- handler: - webhookHandler: select_publication__intent__repeat - intent: repeat -- intent: menu - transitionToScene: home_members_lvl2 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, merci de le répêter - intent: actions.intent.NO_MATCH_1 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, dite un numéro - intent: actions.intent.NO_MATCH_2 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro. - intent: actions.intent.NO_MATCH_FINAL - transitionToScene: search -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, merci de le répêter - intent: actions.intent.NO_INPUT_1 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro, merci de le répêter - intent: actions.intent.NO_INPUT_2 -- handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n’ai pas compris le numéro - intent: actions.intent.NO_INPUT_FINAL - transitionToScene: search -onEnter: - webhookHandler: select_publication -onSlotUpdated: - webhookHandler: select_publication__slot__number -slots: -- name: number - required: true - type: - name: actions.type.Number diff --git a/sdk/custom/scenes/selection_lvl3.yaml b/sdk/custom/scenes/selection_lvl3.yaml deleted file mode 100644 index 72a33a36..00000000 --- a/sdk/custom/scenes/selection_lvl3.yaml +++ /dev/null @@ -1,15 +0,0 @@ -intentEvents: -- handler: - webhookHandler: selection_lvl3__intent__selection_genre_lvl3 - intent: selection_genre_lvl3 -- handler: - webhookHandler: selection_lvl3__intent__selection_thematic_list_lvl3 - intent: selection_thematic_list_lvl3 -- handler: - webhookHandler: selection_lvl3__intent__selection_my_list_lvl3 - intent: selection_my_list_lvl3 -- handler: - webhookHandler: selection_lvl3__intent__selection_all_publication_lvl3 - intent: selection_all_publication_lvl3 -onEnter: - webhookHandler: selection_lvl3 diff --git a/sdk/custom/types/string.yaml b/sdk/custom/types/string.yaml deleted file mode 100644 index 63ddd907..00000000 --- a/sdk/custom/types/string.yaml +++ /dev/null @@ -1 +0,0 @@ -freeText: {} diff --git a/webhooks/functions/package-lock.json b/webhooks/functions/package-lock.json index 77c70813..348a6817 100644 --- a/webhooks/functions/package-lock.json +++ b/webhooks/functions/package-lock.json @@ -449,6 +449,12 @@ "@types/node": "*" } }, + "@types/chai": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz", + "integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==", + "dev": true + }, "@types/connect": { "version": "3.4.35", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", @@ -834,6 +840,12 @@ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, "async-retry": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", @@ -1012,6 +1024,21 @@ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, + "chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } + }, "chainsaw": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", @@ -1030,6 +1057,12 @@ "supports-color": "^7.1.0" } }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, "chokidar": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", @@ -1227,6 +1260,15 @@ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2026,6 +2068,12 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, "get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -2691,6 +2739,15 @@ "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", "optional": true }, + "loupe": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.1.tgz", + "integrity": "sha512-EN1D3jyVmaX4tnajVlfbREU4axL647hLec1h/PXAb8CPDMJiYitcWF2UeLVNttRqaIqQs4x+mRvXf+d+TlDrCA==", + "dev": true, + "requires": { + "get-func-name": "^2.0.0" + } + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -3065,6 +3122,12 @@ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, + "pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true + }, "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -3973,6 +4036,12 @@ "prelude-ls": "^1.2.1" } }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, "type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index 3bf461f1..cf17ae95 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -8,9 +8,10 @@ "deploy": "firebase deploy --only functions", "logs": "firebase functions:log", "build": "tsc", - "test": "mocha --recursive --require ts-node/register src/**/*.test.ts", + "test:run": "mocha --recursive --require ts-node/register", + "test": "npm run test:run2 -- src/**/*.test.ts", "lint": "eslint src/**/*.ts", - "scene-typed": "echo \"// npm run scene-typed \n\n\nexport type TSdkScene = \" $(for I in `ls ../../sdk/test/custom/scenes | cut -d \".\" -f1`; do echo \"'$I' |\"; done) | sed 's/..$/;/' > src/sdk.d.ts", + "scene-typed": "echo \"// npm run scene-typed \n\n\nexport type TSdkScene = \" $(for I in `ls ../../sdk/custom/scenes | cut -d \".\" -f1`; do echo \"'$I' |\"; done) | sed 's/..$/;/' > src/sdk.d.ts", "i18n-typed": "typed-i18next -i src/translation -o src/typings/i18n.d.ts" }, "engines": { @@ -28,9 +29,11 @@ "reflect-metadata": "^0.1.13" }, "devDependencies": { + "@types/chai": "^4.3.0", "@types/mocha": "^9.0.0", "@typescript-eslint/eslint-plugin": "^5.3.1", "@typescript-eslint/parser": "^5.3.1", + "chai": "^4.3.6", "eslint": "^8.2.0", "eslint-config-google": "^0.14.0", "firebase-functions-test": "^0.2.0", diff --git a/webhooks/functions/src/constants.ts b/webhooks/functions/src/constants.ts index 1e99ecc8..b846e483 100644 --- a/webhooks/functions/src/constants.ts +++ b/webhooks/functions/src/constants.ts @@ -10,4 +10,6 @@ export const DEFAULT_LANGUAGE: TLang = 'fr'; export const PADDING = 5; +export const PROJECT_ID = 'edrlab-1'; + type TLang = 'fr' | 'en'; diff --git a/webhooks/functions/src/conversation/test.ts b/webhooks/functions/src/conversation/test.ts deleted file mode 100644 index f880d758..00000000 --- a/webhooks/functions/src/conversation/test.ts +++ /dev/null @@ -1,51 +0,0 @@ -import {TApp} from '..'; - -export const testConversation = (app: TApp) => { - app.handle('test_player_sdk', (conv) => { - const nb = conv.intent.params?.number.resolved; - - switch (nb) { - case 123: - - conv.user.params.player.current.index = 2; - conv.user.params.player.current.playing = true; - conv.user.params.player.current.time = 123; - conv.user.params.player.current.url = 'https://storage.googleapis.com/audiobook_edrlab/webpub/therese_raquin_emile_zola.json'; - conv.user.params.player.history.set('https://storage.googleapis.com/audiobook_edrlab/webpub/therese_raquin_emile_zola.json', { - index: 2, - date: new Date(), - time: 123, - }); - - break; - - case 456: - - break; - case 789: - - break; - } - - console.log('test_PLAYER'); - console.log(conv.user.params); - - conv.add('test.player', {nb}); - }); - - app.handle('test_setup_sdk', (conv) => { - const nb = conv.intent.params?.number.resolved; - - - console.log('HELLLO '); - - - console.log(conv.user.params.bearerToken); - conv.user.params.bearerToken = `test-${nb}`; - console.log(conv.user.params.bearerToken); - - console.log('HELLLO '); - - conv.add('test.setupSdk', {nb}); - }); -}; diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index 631eca69..cca0ebf6 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -1,798 +1,25 @@ -import {conversation, Media } from "@assistant/conversation"; -import * as functions from "firebase-functions"; -import {http as Http, AuthenticationStorage, OpdsFetcher} from "opds-fetcher-parser"; -import {ok as _ok} from "assert"; -import {URL} from "url"; +import { conversation } from "@assistant/conversation"; +import { PROJECT_ID } from "./constants"; +import { IConversationV3App } from "./type"; -// class-transformer -import 'reflect-metadata'; -import { pull, push } from "./database"; -import { StorageDto } from "./model/storage.dto"; -import { getNextLinkFromPublicationsFeed, isPublicationAvailable, isValidHttpUrl } from "./utils"; -import { IConversationWithParams, MediaType, OptionalMediaControl, TPromptItem } from "./type"; -import { persistMediaPlayer } from "./service/persist"; -import { listPublication } from "./service/listPublication"; -import { selectPublication } from "./service/selectPublication"; -import { testConversation } from "./conversation/test"; -import { listGroups } from "./service/listGroups"; -import { selectGroup } from "./service/selectGroups"; -import { ALL_PUBLICATION_LIST_URL, GENRE_LIST_URL, PADDING, SEARCH_URL, SELECTION_URL, THEMATIC_LIST_URL, API_BASE_URL } from "./constants"; -import { i18n, t, TI18nKey } from "./translation"; -import { DefaultScenes } from "@assistant/conversation/dist/conversation/handler"; - -const BEARER_TOKEN_NOT_DEFINED = "bearer token not defined"; - -const app = conversation(); -export type TApp = typeof app; +const app = conversation({ + verification: PROJECT_ID, + debug: true, +}) as IConversationV3App; const appHandle: typeof app.handle = app.handle.bind(app); -const __ok:(value: unknown, message?: TI18nKey) => asserts value = _ok.bind(_ok); -export const ok: typeof __ok = (v, m) => { - return __ok(v, m ? t(m): undefined); -} - app.handle = (path, fn) => { const ret = appHandle(path, async (conv) => { - await Promise.resolve(fn(conv)); - - const bearerToken = conv.user.params.bearerToken; - try { - - ok(bearerToken, 'error.bearerTokenNotDefined'); - ok(bearerToken !== BEARER_TOKEN_NOT_DEFINED, 'error.bearerTokenNotDefined') - - const data = conv.user.params.extract(); - await push(bearerToken, data); - } catch (e) { - - console.error("ERROR TO save user storage to the database"); - console.error(e); - } - - console.log("----------"); - console.log(conv.user.params); - console.log("----------"); - - - // reset user storage - // @ts-ignore - conv.user.params = { - bearerToken, - }; - + await Promise.resolve(fn({conv})); }); - return ret; -}; - -// load test conversationnel -// not used in prod MODE -// @TODO Disable it in PROD-MODE -testConversation(app); - -// catch(catcher: ExceptionHandler): ConversationV3App -// ExceptionHandler(conv: TConversation, error: Error): any -app.catch((conv, error) => { - // conv.add('error.catch', { error: error.toString() }); - - console.log('ERROR'); - console.log(error); - - // conv.add(error.toString()); - - conv.scene.next.name = conv.scene.name; // loop -}); - -// middleware(middleware: ConversationV3Middleware): ConversationV3App -// ConversationV3Middleware(conv: ConversationV3, framework: BuiltinFrameworkMetadata): void | ConversationV3 & TConversationPlugin | Promise | Promise -app.middleware(async (conv: IConversationWithParams) => { - - if (!conv.session.params) { - conv.session.params = { - groupListUrl: "", - pubListUrl: "", - query: "", - nextUrlCounter: 0, - scene: 'home_lvl1', - tocStart: 0, - }; - } - - const bearerTokenRaw = conv.user.params.bearerToken; - const bearerToken = typeof bearerTokenRaw === "string" && bearerTokenRaw ? conv.user.params.bearerToken : BEARER_TOKEN_NOT_DEFINED; - - const authenticationStorage = new AuthenticationStorage(); - authenticationStorage.setAuthenticationToken({ - accessToken: bearerToken, - authenticationUrl: API_BASE_URL, - }); - const http = new Http(undefined, authenticationStorage); - - conv.di = { - opds: new OpdsFetcher(http), - }; - - const locale = conv.user.locale; - await i18n.changeLanguage(locale); - - try { - const data = await pull(bearerToken); - - // @ts-ignore - console.log(data.player.history); - const instance = StorageDto.create(data, bearerToken); - conv.user.params = instance; - - } catch (e) { - console.error('Middleware critical error firebase firestore'); - console.error(e); - - conv.user.params = StorageDto.create(undefined, bearerToken); - } - - console.log(conv.user.params); - console.log('=========='); - console.log(conv.request); - console.log('----------'); - - ok(conv.user.params instanceof StorageDto); - - const convAdd: IConversationWithParams["add"] = conv.add.bind(conv); - conv.add = function (...promptItems) { - - const item: TPromptItem | undefined = promptItems[0] instanceof Media - ? promptItems[0] - : typeof promptItems[0] === "string" - ? t(promptItems[0], typeof promptItems[1] === "object" ? promptItems[1] : undefined) - : undefined; - - ok(item, 'error.convadd'); - - const ret = convAdd(item); - - return ret; - } - - // void -}); - -// ---------------- -// -// CONVERSATION START -// -// ---------------- - -app.handle('cancel', (conv) => { - // Implement your code here - // conv.add("cancel"); -}); - -app.handle('main', (conv) => { - - console.log(conv.add); - - conv.add('main.welcome'); - - conv.scene.next.name = "home_members_lvl2"; -}); - -app.handle('home_lvl1', (conv) => { - - conv.add('home.welcome'); - - // wait intent - // conv.scene.next.name -}); - -app.handle('test_webhook', (conv) => { - conv.add('test.webhook', { message: functions.config().debug.message || '' }); - console.log('TEST OK'); - - conv.scene.next.name = conv.scene.name; -}); - -app.handle('home_lvl1__intent__get_info_association_lvl1', (conv) => { - - conv.add('home.information'); - - conv.scene.next.name = "home_lvl1"; -}); - -app.handle('home_lvl1__intent__enter_member_space_lvl1', (conv) => { - - conv.scene.next.name = "home_lvl1_AccountLinking"; -}); - -app.handle('home_lvl1__intent__resume_listening_player', (conv) => { - - conv.scene.next.name = "home_lvl1"; -}); - -app.handle('home_lvl1__intent__listen_audiobook_lvl1', (conv) => { - - conv.scene.next.name = "home_lvl1_AccountLinking"; -}); - -app.handle('home_members_lvl2', (conv) => { - - conv.add('homeMembers.welcome1'); - conv.add('homeMembers.welcome2'); - - conv.session.params.tocStart = 0; -}); - -app.handle('home_members_lvl2__intent__listen_audiobook_lvl2', (conv) => { - // void - - console.log('listen_audiobook_lvl2'); - - // first entry point for search - // - // VOID - // - // search_livre_lvl2 is the main entry point - - conv.scene.next.name = "search"; -}); - -app.handle('home_members_lvl2__intent__resume_audiobook_lvl2', (conv) => { - - const url = conv.user.params.player.current.url; - if (!isValidHttpUrl(url)) { - conv.scene.next.name = "home_members_lvl2"; - conv.add('homeMembers.resumeAudiobook.noCurrentListening'); - } else - conv.scene.next.name = "ask_to_resume_listening_at_last_offset"; -}); - -app.handle('home_members__intent__selection_audiobook_lvl2', (conv) => { - - conv.scene.next.name = "selection_lvl3"; -}); - -app.handle('selection_lvl3', (conv) => { - - conv.add("homeMembers.selection.welcome"); - - // reset selection context - // conv.user.params.selection.url = undefined; - // conv.user.params.selection.topUrl = undefined; - conv.session.params.pubListUrl = ""; - conv.session.params.groupListUrl = ""; - conv.session.params.nextUrlCounter = 0; - - conv.session.params.scene = 'selection_lvl3'; - - // wait intent - // conv.scene.next.name -}); - -app.handle('selection_lvl3__intent__selection_genre_lvl3', async (conv) => { - - const url = GENRE_LIST_URL; - conv.session.params.groupListUrl = url; - conv.scene.next.name = 'select_group'; - -}); - -app.handle('selection_lvl3__intent__selection_thematic_list_lvl3', async (conv) => { - - const url = THEMATIC_LIST_URL; - conv.session.params.groupListUrl = url; - conv.scene.next.name = 'select_group'; -}); - -app.handle('selection_lvl3__intent__selection_my_list_lvl3', async (conv) => { - - conv.session.params.pubListUrl = SELECTION_URL; - conv.scene.next.name = 'select_publication'; - - conv.session.params.nextUrlCounter = 0; - - console.log('selection_my_list_lvl3 EXIT'); -}); - -app.handle('selection_lvl3__intent__selection_all_publication_lvl3', async (conv) => { - - conv.session.params.pubListUrl = ALL_PUBLICATION_LIST_URL; - conv.scene.next.name = 'select_publication'; - - conv.session.params.nextUrlCounter = 0; -}); - -app.handle('select_group', async (conv) => { - - // conv.add('homeMembers.selection.listAfterSelection'); - - const url = conv.session.params.groupListUrl; - ok(isValidHttpUrl(url)); - await listGroups(url, conv); - - // wait slot number or intent -}); - -app.handle('select_group__intent__stop', (conv) => { - - conv.scene.next.name = 'home_members_lvl2'; -}); - -app.handle('select_group__intent__menu', (conv) => { - - conv.scene.next.name = 'home_members_lvl2'; -}); - -app.handle('select_group__slot__number', async (conv) => { - console.log('select_group_number START'); - - const number = conv.intent.params?.number.resolved; - - const groupUrl = conv.session.params.groupListUrl; - ok(isValidHttpUrl(groupUrl), 'error.selectionListNotDefined'); - const url = await selectGroup(groupUrl, number, conv); - - if (url) { - ok(isValidHttpUrl(url), 'error.selectionPubNotDefined'); - - conv.session.params.pubListUrl = url; - conv.session.params.nextUrlCounter = 0; - conv.scene.next.name = 'select_publication'; - } else { - // conv.scene.next.name = 'select_group'; - } - - console.log('select_group_number END'); -}); - -app.handle("ask_to_resume_listening_at_last_offset", async (conv) => { - - console.log("start: ask_to_resume_last_offset"); - - const { url, index, time } = conv.user.params.player.current; - if (isValidHttpUrl(url) && ((index && index > 0) || (time && time > 0))) { - console.log("ask to resume enabled , wait yes or no"); - // ask yes or no in the no-code scene - // const history = conv.user.params.player[url]; - // const date = history.d; - // TODO: use the date info - - conv.add('player.askResumeLastOffset'); - - // wait intent - } else { - console.log('no need to ask to resume'); - conv.scene.next.name = 'player'; - } -}); - -const sayAudiobookTitle = async (conv: IConversationWithParams, url: string) => { - - const webpub = await conv.di.opds.webpubRequest(url); - const title = webpub.title; - - if (title) { - conv.add('player.start', {title}); - } -}; - -app.handle('ask_to_resume_listening_at_last_offset__intent__yes', async (conv) => { - - const url = conv.user.params.player.current.url; - ok(isValidHttpUrl(url)); - await sayAudiobookTitle(conv, url); - - conv.scene.next.name = 'player'; -}); - -app.handle("ask_to_resume_listening_at_last_offset__intent__no", async (conv) => { - - const url = conv.user.params.player.current.url; - ok(isValidHttpUrl(url), 'error.urlNotValid'); - console.log("erase ", url, " resume listening NO"); - await sayAudiobookTitle(conv, url); - - conv.user.params.player.current.index = 0; - conv.user.params.player.current.time = 0; - conv.scene.next.name = 'player'; -}); - -app.handle('search', (conv) => { - - conv.add('homeMembers.search'); - - conv.session.params.scene = 'search'; - - conv.session.params.pubListUrl = ""; - conv.session.params.groupListUrl = ""; - - // wait query intent -}); - -app.handle('search__slot__query', async (conv) => { - // void - - const query = conv.intent.params?.query.resolved; - console.log('search_slot_query', query); - - ok(typeof query === 'string', 'error.noQuery'); - conv.session.params.query = query; - - // save url to session storage (next link) - const url = SEARCH_URL.replace('{query}', encodeURIComponent(query)); - console.log('search URL: ', url); - - ok(isValidHttpUrl(url)); - conv.session.params.pubListUrl = url; - conv.session.params.nextUrlCounter = 0; - conv.scene.next.name = "select_publication"; - -}); - -app.handle('search__intent__resume_listening_player', (conv) => { - - conv.scene.next.name = "search"; -}); - -app.handle('select_publication', async (conv) => { - - - const url = conv.session.params.pubListUrl; - ok(isValidHttpUrl(url)); - await listPublication(url, conv); - - // wait intent -}); - -app.handle('select_publication__intent__stop', (conv) => { - - conv.scene.next.name = 'home_members_lvl2'; -}); - -app.handle('select_publication__intent__resume_listening_player', (conv) => { - - conv.scene.next.name = "select_publication"; -}); - -app.handle('select_publication__intent__next', async (conv) => { - - const url = conv.session.params.pubListUrl; - ok(isValidHttpUrl(url)); - const nextUrl = await getNextLinkFromPublicationsFeed(conv.di.opds, url); - if (nextUrl && await isPublicationAvailable(conv.di.opds, nextUrl)) { - conv.session.params.pubListUrl = nextUrl; - conv.session.params.nextUrlCounter++; - } else { - conv.add('homeMembers.selection.noNext') + '\n'; - } - - conv.scene.next.name = "select_publication"; -}); - -app.handle('select_publication__slot__number', async (conv) => { - console.log('select_publication_number START'); - - const number = conv.intent.params?.number.resolved; - - console.log('NUMBER: ', number); - - const url = conv.session.params.pubListUrl; - await selectPublication(url, number, conv); - - console.log('select_publication_number END'); -}); - -app.handle('select_publication__intent__repeat', async (conv) => { - - conv.scene.next.name = 'select_publication'; -}); - -app.handle("player", async (conv) => { - - const url = conv.user.params.player.current.url; - ok(isValidHttpUrl(url), 'error.urlNotValid'); - console.log("Player URL:", url); - - const startIndexRaw = conv.user.params.player.current.index; - const startTimeRaw = conv.user.params.player.current.time; - - const webpub = await conv.di.opds.webpubRequest(url); - ok(webpub, 'error.webpubNotDefined'); - - let startIndex = (startIndexRaw && startIndexRaw > -1 && startIndexRaw <= webpub.readingOrders.length) - ? startIndexRaw - : 0; - - const startTime = (startTimeRaw && startTimeRaw > -1) - ? startTimeRaw <= (webpub.readingOrders[startIndex].duration || Infinity) - ? startTimeRaw - : (startIndex += 1, startTimeRaw) - : 0; - - startIndex = startIndex <= webpub.readingOrders.length - ? startIndex - : 0; - - const mediaObjects = webpub.readingOrders - .map((v, i) => ({ - name: `${webpub.title || ''} - ${i + 1}`, - url: v.url, - image: { - large: { - alt: webpub.title, - url: webpub.cover || '', - }, - }, - })).slice(startIndex); - - console.log('Media list'); - console.log(mediaObjects); - console.log('Start Index = ', startIndex, ' Start Time = ', startTime, ' Start Time'); - - conv.add( - new Media({ - mediaObjects: mediaObjects, - mediaType: MediaType.Audio, - optionalMediaControls: [OptionalMediaControl.Paused, OptionalMediaControl.Stopped], - startOffset: `${startTime}s`, - }), - ); - - conv.session.params.tocStart = 0; // reset toc -}); - -// ---------- -// PLAYER -// ---------- - - -// //////////////////////// -// Media PLAYER CONTEXT // -// //////////////////////// - - -app.handle('player__intent__resume_listening_player', (conv) => { - persistMediaPlayer(conv); - - // // Acknowledge pause/stop - // conv.add(new Media({ - // mediaType: 'MEDIA_STATUS_ACK' - // })); - - conv.scene.next.name = 'player'; -}); - -// overhided by the google nest player -// 'avance' : avance de x seconds -// 'repete' : repete la track -// 'avance de 30 secondes : ne fait rien -// -// app.handle('player__intent__repeat_player', (conv) => { -// persistMediaPlayer(conv); - -// if (conv.user.params.player.current.time) -// conv.user.params.player.current.time -= 30; - -// conv.scene.next.name = 'player'; -// }); - -// app.handle('player__intent__jump_30sec_player', (conv) => { -// persistMediaPlayer(conv); - -// if (conv.user.params.player.current.time) -// conv.user.params.player.current.time += 30; - -// conv.scene.next.name = 'player'; -// }); - -app.handle('player__intent__listen_toc', (conv) => { - persistMediaPlayer(conv); - - // conv.add('player.notAvailable'); - - // // Acknowledge pause/stop - // conv.add(new Media({ - // mediaType: 'MEDIA_STATUS_ACK' - // })); - - // conv.scene.next.name = 'player'; - conv.scene.next.name = 'player_toc'; -}); - -app.handle('player__intent__menu', (conv) => { - persistMediaPlayer(conv); - - // Acknowledge pause/stop - conv.add(new Media({ - mediaType: MediaType.MediaStatusACK, - })); - - conv.scene.next.name = "home_members_lvl2"; -}); - -app.handle('player__intent__remaining_time_player', async (conv) => { - persistMediaPlayer(conv); - - const url = conv.user.params?.player?.current?.url; - ok(url, 'error.urlNotValid') - ok(isValidHttpUrl(url), 'error.urlNotValid'); - - const webpub = await conv.di.opds.webpubRequest(url); - ok(webpub, 'error.webpubNotDefined'); - - const index = conv.user.params.player.current.index || 0; - const time = conv.user.params.player.current.time || 0; - - let minutes = 0; - if (Array.isArray(webpub.readingOrders)) { - let remainingTime = 0; - for (let i = index + 1; i < webpub.readingOrders.length; i += 1) { - remainingTime += webpub.readingOrders[i].duration || 0; - } - const pos = (v) => (v < 0 ? 0 : v); - remainingTime += pos((webpub.readingOrders[index].duration || 0) - time); - - if (remainingTime >= 60) { - minutes = Math.floor(remainingTime / 60); - } - } - - const hours = Math.floor(minutes / 60); - if (hours) { - minutes = minutes % 60; - conv.add('player.remaining.hoursAndMinute', { hours, minutes }); - } else { - conv.add('player.remaining.minute', { minutes }); - } - - // // Acknowledge pause/stop - // conv.add(new Media({ - // mediaType: 'MEDIA_STATUS_ACK' - // })); - - conv.scene.next.name = 'player'; -}); - -app.handle('player_toc', async (conv) => { - - const url = conv.user.params.player?.current?.url; - - if (!url) { - conv.add('homeMembers.resumeAudiobook.noCurrentListening'); - conv.scene.next.name = 'home_members_lvl2'; - return ; - } - - ok(isValidHttpUrl(url), 'error.urlNotValid'); - - const webpub = await conv.di.opds.webpubRequest(url); - - const tocSliceStart = conv.session.params.tocStart; - const toc = webpub.toc; - - if (toc) { - - const textArray = toc - .map(({ title }, i) => t('homeMembers.list.numero', { title, i: i + 1 })) - .filter((v) => v) - .slice(tocSliceStart, tocSliceStart + PADDING); - const text = textArray.join("") + '\n' + t('player.toc.numero'); - - conv.add('free', { text }); - - } else { - - conv.add('player.toc.notFound'); - } - - // conv.scene.next.name = "player"; -}); - -app.handle('player_toc__slot__number', async (conv) => { - - const url = conv.user.params.player.current.url; - ok(isValidHttpUrl(url), 'error.urlNotValid'); - const number = conv.intent.params?.number.resolved; - ok(typeof number === "number"); - - const webpub = await conv.di.opds.webpubRequest(url); - - const toc = webpub.toc; - const tocSliceStart = conv.session.params.tocStart; - - if (toc) { - // const tocs = toc.slice(tocSliceStart, tocSliceStart + PADDING); - const item = toc[number - 1]; - - if (item) { - const itemUrl = new URL(item.url); - const time = parseInt(itemUrl.hash.split("#t=")[1], 10); - - const readingOrders = webpub.readingOrders; - const index = readingOrders.findIndex(({url}) => url.startsWith(itemUrl.origin + itemUrl.pathname)); - - if (index > -1 && time > -1) { - conv.user.params.player.current.time = time; - conv.user.params.player.current.index = index; - } - } - } - - conv.scene.next.name = 'player'; -}); - -app.handle('player_toc__intent__next', async (conv) => { - - const url = conv.user.params.player.current.url; - ok(isValidHttpUrl(url), 'error.urlNotValid'); - - const webpub = await conv.di.opds.webpubRequest(url); - - const toc = webpub.toc; - const len = toc?.length || Infinity; - - if (conv.session.params.tocStart < len - PADDING) { - conv.session.params.tocStart += PADDING; - } else { - conv.add('player.toc.noNext'); - } - conv.scene.next.name = 'player_toc'; -}); - -app.handle('player_toc__intent__repeat', (conv) => { - - conv.scene.next.name = 'player_toc'; -}); - -app.handle('player_toc__intent__resume_listening_player', (conv) => { - - conv.scene.next.name = 'player'; -}); - -// //////////////////////// -// Media PLAYET CONTEXT // -// //////////////////////// - -// Media status -app.handle('media_status', (conv) => { - console.log('MediaStatus START'); - const mediaStatus = conv.intent.params?.MEDIA_STATUS.resolved; - console.log('MediaStatus : ', mediaStatus); - switch (mediaStatus) { - case 'FINISHED': - persistMediaPlayer(conv); - conv.scene.next.name = "home_members_lvl2"; - - // void - break; - case 'FAILED': - - // void - break; - case 'PAUSED': - persistMediaPlayer(conv); - // Acknowledge pause/stop - conv.add(new Media({ - mediaType: MediaType.MediaStatusACK, - })); +} - break; - case 'STOPPED': - persistMediaPlayer(conv); - // Acknowledge pause/stop - conv.add(new Media({ - mediaType: MediaType.MediaStatusACK, - })); - // disable because need to exit the app instead - // @ts-ignore - conv.scene.next.name = 'actions.scene.END_CONVERSATION'; - break; - default: - conv.add('player.mediaStatus.notCorrect'); - } +app.handle('main', async ({conv}) => { - console.log('MediaStatus END'); -}); + conv.add('main'); -exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app); +}); \ No newline at end of file diff --git a/webhooks/functions/src/database/firestore.ts b/webhooks/functions/src/model/database/firestore.ts similarity index 100% rename from webhooks/functions/src/database/firestore.ts rename to webhooks/functions/src/model/database/firestore.ts diff --git a/webhooks/functions/src/database/index.ts b/webhooks/functions/src/model/database/index.ts similarity index 100% rename from webhooks/functions/src/database/index.ts rename to webhooks/functions/src/model/database/index.ts diff --git a/webhooks/functions/src/model/storage.model.ts b/webhooks/functions/src/model/storage.model.ts new file mode 100644 index 00000000..162976a6 --- /dev/null +++ b/webhooks/functions/src/model/storage.model.ts @@ -0,0 +1,51 @@ +import { ok } from 'assert'; +import { pull, push } from './database'; +import { StorageDto } from './storage.dto'; + +export class StorageModel { + + private _bearer: string; + private _storage: StorageDto; + private static _singleton: boolean; + + constructor(bearerToken: string, store: StorageDto) { + + if (StorageModel._singleton) { + throw new Error("already instancied"); + } + + ok(bearerToken); + this._bearer = bearerToken; + + ok(store instanceof StorageDto); + this._storage = store; + + StorageModel._singleton = true; + } + + public static async create(bearerToken: string) { + + ok(""); + + let store: StorageDto; + try { + const data = await pull(bearerToken); + store = StorageDto.create(data, bearerToken); + } catch (e) { + console.error("StorageModel Create Error", e); + store = StorageDto.create(undefined, bearerToken); + } + return new StorageModel(bearerToken, store); + } + + public async save() { + + const data = this.store.extract(); + await push(this._bearer, data); + } + + get store() { + return this._storage; + } + +} \ No newline at end of file diff --git a/webhooks/functions/src/model/storage.test.ts b/webhooks/functions/src/model/storage.test.ts index fc8da27a..da463611 100644 --- a/webhooks/functions/src/model/storage.test.ts +++ b/webhooks/functions/src/model/storage.test.ts @@ -3,6 +3,9 @@ import {StorageDto} from './storage.dto'; import * as assert from 'assert'; import {classToPlain} from 'class-transformer'; import {inspect} from 'util'; +import * as chai from 'chai'; + +chai.should(); describe('storage DTO', () => { it('create storage object', () => { @@ -232,3 +235,12 @@ describe('storage DTO', () => { }); }); }); + + +describe('storage Model', () => { + done(); + + it('create a storeModel', async (done) => { + }) + +}); \ No newline at end of file diff --git a/webhooks/functions/src/sdk.d.ts b/webhooks/functions/src/sdk.d.ts deleted file mode 100644 index 2637b4a7..00000000 --- a/webhooks/functions/src/sdk.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -// npm run scene-typed ; - - -export type TSdkScene = 'ask_to_resume_listening_at_last_offset' | 'home_lvl1' | 'home_lvl1_AccountLinking' | 'home_members_lvl2' | 'player' | 'player_toc' | 'search' | 'select_group' | 'select_publication' | 'selection_lvl3'; diff --git a/webhooks/functions/src/service/listGroups.ts b/webhooks/functions/src/service/listGroups.ts deleted file mode 100644 index cb014b58..00000000 --- a/webhooks/functions/src/service/listGroups.ts +++ /dev/null @@ -1,30 +0,0 @@ -import {TSdkScene} from '../sdk'; -import {IConversationWithParams} from '../type'; -import {getGroupsFromFeed, isValidHttpUrl} from '../utils'; -import {ok} from 'assert'; -import {t} from '../translation'; - -export async function listGroups(url: string, conv: IConversationWithParams, errorScene: TSdkScene = conv.scene.name) { - ok(isValidHttpUrl(url), 'url not valid'); - const list = await getGroupsFromFeed(conv.di.opds, url); - console.log('SELECTIONS: ', list); - - const length = list.length; - if (length > 1) { - let text = t('homeMembers.list.numberSelection', {length}); - list.map(({title}, i) => { - text += t('homeMembers.list.numero', {i: i + 1, title}); - }); - - text += '\n'; - text += t('homeMembers.selection.listAfterSelection'); - - conv.add('free', {text}); - } else if (length === 1) { - conv.scene.next.name = 'select_publication'; - conv.session.params.pubListUrl = list[0].groupUrl; - } else { - conv.scene.next.name = errorScene; - conv.add('homeMembers.list.noResult'); - } -} diff --git a/webhooks/functions/src/service/listPublication.ts b/webhooks/functions/src/service/listPublication.ts deleted file mode 100644 index b9cdc678..00000000 --- a/webhooks/functions/src/service/listPublication.ts +++ /dev/null @@ -1,45 +0,0 @@ -import {TSdkScene} from '../sdk'; -import {IConversationWithParams} from '../type'; -import {getNextLinkFromPublicationsFeed, getPubsFromFeed, isPublicationAvailable, isValidHttpUrl} from '../utils'; -import {ok} from 'assert'; -import {t} from '../translation'; - -export async function listPublication(url: string, conv: IConversationWithParams, - errorScene: TSdkScene = conv.session?.params?.scene) { - ok(isValidHttpUrl(url), 'url not valid'); - const [list, totalLength] = await getPubsFromFeed(conv.di.opds, url); - const nextUrl = await getNextLinkFromPublicationsFeed(conv.di.opds, url); - console.log('PUBs: ', list); - - const length = list.length; - if (length > 1 || conv.session.params.nextUrlCounter) { - const page = conv.session.params.nextUrlCounter + 1; - const nextAvailable = !!nextUrl && await isPublicationAvailable(conv.di.opds, nextUrl); - let text = ''; - if (page === 1) { - text += t('homeMembers.list.numberPublication', {length: totalLength}) + '\n'; - } - if (page > 1 || nextAvailable) { - text += t('homeMembers.list.pagePublication', {page}) + '\n'; - } - - list.map(({title, author}, i) => { - text += t('homeMembers.list.numeroWithAuthor', - {i: i + 1, title, author: author ? t('homeMembers.list.numeroWithAuthorOf', {author}) : ''}); - }); - - text += '\n'; - text += t('homeMembers.selection.publication') + '\n'; - if (nextAvailable) { - text += t('homeMembers.selection.next'); - } - - conv.add('free', {text}); - } else if (length === 1) { - conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; - conv.user.params.player.current.url = list[0].webpuburl; - } else { - conv.scene.next.name = errorScene; - conv.add('homeMembers.list.noResult'); - } -} diff --git a/webhooks/functions/src/service/persist.ts b/webhooks/functions/src/service/persist.ts deleted file mode 100644 index ab3ec02c..00000000 --- a/webhooks/functions/src/service/persist.ts +++ /dev/null @@ -1,27 +0,0 @@ -import {isValidHttpUrl} from '../utils'; -import {IConversationWithParams} from '../type'; -import {ok} from '..'; - -export function persistMediaPlayer(conv: IConversationWithParams) { - if (!conv.request.context) { - console.log('NO conv.request.context !!'); - return; - } - - // Persist the media progress value - - const _progress = conv.request.context?.media?.progress || '0'; - const progress = parseInt(_progress, 10); - const index = conv.request.context?.media?.index || 0; - const url = conv.user.params.player.current.url; - ok(isValidHttpUrl(url), 'error.urlNotValid'); - - conv.user.params.player.current.index = index; - conv.user.params.player.current.time = progress; - - conv.user.params.player.history.set(url, { - index, - time: progress, - date: new Date(), - }); -} diff --git a/webhooks/functions/src/service/selectGroups.ts b/webhooks/functions/src/service/selectGroups.ts deleted file mode 100644 index ee5de1a6..00000000 --- a/webhooks/functions/src/service/selectGroups.ts +++ /dev/null @@ -1,21 +0,0 @@ -import {ok} from '..'; -import {IConversationWithParams} from '../type'; -import {getGroupsFromFeed, isValidHttpUrl} from '../utils'; - -export async function selectGroup(url: string, number: number, conv: IConversationWithParams) { - ok(isValidHttpUrl(url), 'error.urlNotValid'); - const list = await getGroupsFromFeed(conv.di.opds, url); - const group = list[number - 1]; - if (!group) { - console.log('NO GROUPS found !!'); - conv.add('homeMembers.list.wrongNumber', {number}); - conv.scene.next.name = conv.scene.name; // loop selection or search - - return undefined; - } - - console.log('Groups: ', group); - - return group.groupUrl; - // conv.scene.next.name = 'select_pub_after_selection'; -} diff --git a/webhooks/functions/src/service/selectPublication.ts b/webhooks/functions/src/service/selectPublication.ts deleted file mode 100644 index b97d2e89..00000000 --- a/webhooks/functions/src/service/selectPublication.ts +++ /dev/null @@ -1,26 +0,0 @@ -import {ok} from '..'; -import {IConversationWithParams} from '../type'; -import {getPubsFromFeed, isValidHttpUrl} from '../utils'; - -export async function selectPublication(url: string, number: number, conv: IConversationWithParams) { - ok(isValidHttpUrl(url), 'error.urlNotValid'); - const [list] = await getPubsFromFeed(conv.di.opds, url); - const pub = list[number - 1]; - if (!pub) { - console.log('NO PUBS found !!'); - conv.add('homeMembers.list.wrongNumber', {number}); - conv.scene.next.name = conv.scene.name; // loop selection or search - - return; - } - - console.log('PUB: ', pub); - - const urlWebpub = pub.webpuburl; - const history = conv.user.params.player.history.get(urlWebpub); - conv.user.params.player.current.index = history ? history.index : 0; - conv.user.params.player.current.time = history ? history.time : 0; - conv.user.params.player.current.url = urlWebpub; - - conv.scene.next.name = 'ask_to_resume_listening_at_last_offset'; -} diff --git a/webhooks/functions/src/type.ts b/webhooks/functions/src/type.ts index 8ad832c4..e45e58a6 100644 --- a/webhooks/functions/src/type.ts +++ b/webhooks/functions/src/type.ts @@ -1,10 +1,6 @@ -import { ConversationV3 } from "@assistant/conversation"; +import { ConversationV3, ConversationV3App } from "@assistant/conversation"; import { Media } from "@assistant/conversation/dist/api/schema"; -import { User, Scene } from "@assistant/conversation/dist/conversation/handler"; import { TI18nKey } from "./translation"; -import { StorageDto } from "./model/storage.dto"; -import { TSdkScene } from "./sdk"; -import { OpdsFetcher } from "opds-fetcher-parser"; export enum MediaType { Audio = 'AUDIO', @@ -20,30 +16,9 @@ export enum OptionalMediaControl { export type TPromptItem = TI18nKey | {[k: string]: any} | Media; //PromtItem type from @assistant/conversation -interface IUser extends User { - params: StorageDto; -} -interface IScene extends Scene { - next: { - name: TSdkScene; - }, - name: TSdkScene; -} export interface IConversationWithParams extends ConversationV3 { - di: { - opds: OpdsFetcher; - }; - user: IUser; - scene: IScene; - add: (...promptItems: TPromptItem[]) => this; - session: { - params: { - pubListUrl: string; - groupListUrl: string; - query: string; - scene: TSdkScene; - nextUrlCounter: number; - tocStart: number; - } - } } + +export interface IConversationV3App extends ConversationV3App { + handle: (path: string, fn: (obj: any) => any) => this; +} \ No newline at end of file diff --git a/webhooks/functions/src/utils/index.ts b/webhooks/functions/src/utils/index.ts deleted file mode 100644 index b6f0cf92..00000000 --- a/webhooks/functions/src/utils/index.ts +++ /dev/null @@ -1,85 +0,0 @@ -import {OpdsFetcher} from 'opds-fetcher-parser'; -import * as assert from 'assert'; -import {IOpdsLinkView} from 'opds-fetcher-parser/build/src/interface/opds'; -import {URL} from 'url'; - -export function isValidHttpUrl(url: string | undefined): url is string { - let _url: URL; - - try { - if (!url) return false; - _url = new URL(url); - } catch (_) { - return false; - } - - return _url.protocol === 'http:' || _url.protocol === 'https:'; -} - -export async function getPubsFromFeed(opds: OpdsFetcher, url: string): Promise<[{ - title: string; - author: string; - webpuburl: string; -}[], number]> { - const feed = await opds.feedRequest(url); - - assert.ok(Array.isArray(feed.publications), 'no publications'); - const list = feed.publications - .filter(({openAccessLinks: l}) /* : l is IOpdsLinkView[]*/ => { - return ( - Array.isArray(l) && - l[0] && - isValidHttpUrl(l[0].url) - ); - }) - .slice(0, 5) - .map(({title, authors, openAccessLinks}) => ({ - title: title, - author: Array.isArray(authors) ? authors[0].name : '', - webpuburl: (openAccessLinks as IOpdsLinkView[])[0].url, - })); - - return [list, feed.metadata?.numberOfItems || list.length]; -} - -export async function getGroupsFromFeed(opds: OpdsFetcher, url: string) { - const feed = await opds.feedRequest(url); - - assert.ok(Array.isArray(feed.groups), 'no groups'); - const list = feed.groups - .filter(({selfLink: l}) /* : l is IOpdsLinkView[]*/ => { - return l?.title && l?.url && isValidHttpUrl(l.url); - }) - .slice(0, 5) - .map(({selfLink: {title, url}}) => ({ - title: title, - groupUrl: url, - })); - - return list; -} - -export async function isPublicationAvailable(opds: OpdsFetcher, url: string): Promise { - assert.ok(isValidHttpUrl(url)); - const [pubs] = await getPubsFromFeed(opds, url); - - if (pubs.length) { - return true; - } - return false; -} - -export async function getNextLinkFromPublicationsFeed(opds: OpdsFetcher, url: string): Promise { - assert.ok(isValidHttpUrl(url)); - const feed = await opds.feedRequest(url); - - try { - const nextLink = feed.links?.next[0].url; - if (nextLink && await isPublicationAvailable(opds, nextLink)) { - return nextLink; - } else { - } - } catch { - } - return undefined; -} From c503ee1fb81481ee93bba85d6f39e6bc0b02b3b6 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 2 Feb 2022 17:20:29 +0100 Subject: [PATCH 087/180] clean model and test it and create a first controller with assistant lib --- webhooks/functions/package-lock.json | 197 ++++++++++++++++++ webhooks/functions/package.json | 6 +- .../functions/src/controller/assistant.ts | 18 ++ webhooks/functions/src/index.ts | 22 +- webhooks/functions/src/model/storage.dto.ts | 3 +- webhooks/functions/src/model/storage.model.ts | 5 +- webhooks/functions/src/model/storage.test.ts | 55 ++++- 7 files changed, 279 insertions(+), 27 deletions(-) create mode 100644 webhooks/functions/src/controller/assistant.ts diff --git a/webhooks/functions/package-lock.json b/webhooks/functions/package-lock.json index 348a6817..9fca7a55 100644 --- a/webhooks/functions/package-lock.json +++ b/webhooks/functions/package-lock.json @@ -405,6 +405,41 @@ "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", "optional": true }, + "@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", + "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@sinonjs/samsam": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.1.tgz", + "integrity": "sha512-cZ7rKJTLiE7u7Wi/v9Hc2fs3Ucc3jrWeMgPHbbTCeVAB2S0wOBbYlkJVeNSL04i7fdhT8wIbDq1zhC/PXTD2SA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, "@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", @@ -570,6 +605,12 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz", "integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==" }, + "@types/proxyquire": { + "version": "1.3.28", + "resolved": "https://registry.npmjs.org/@types/proxyquire/-/proxyquire-1.3.28.tgz", + "integrity": "sha512-SQaNzWQ2YZSr7FqAyPPiA3FYpux2Lqh3HWMZQk47x3xbMCqgC/w0dY3dw9rGqlweDDkrySQBcaScXWeR+Yb11Q==", + "dev": true + }, "@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", @@ -589,6 +630,15 @@ "@types/node": "*" } }, + "@types/sinon": { + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.9.tgz", + "integrity": "sha512-xGZVAe61omKnVGedBdTbAveuJ5QyI0LrMIcp0hc1LmVI5IEjs5qG4fM0sv9GIBA2JVoKuf7332IjQX4y5qqMMQ==", + "dev": true, + "requires": { + "@sinonjs/fake-timers": "^7.1.0" + } + }, "@types/validator": { "version": "13.6.6", "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.6.6.tgz", @@ -1822,6 +1872,16 @@ "unit-compare": "^1.0.1" } }, + "fill-keys": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz", + "integrity": "sha1-mo+jb06K1jTjv2tPPIiCVRRS6yA=", + "dev": true, + "requires": { + "is-object": "~1.0.1", + "merge-descriptors": "~1.0.0" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -2022,6 +2082,12 @@ } } }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", @@ -2214,6 +2280,15 @@ "har-schema": "^2.0.0" } }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -2369,6 +2444,15 @@ "binary-extensions": "^2.0.0" } }, + "is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2407,6 +2491,12 @@ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "optional": true }, + "is-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "dev": true + }, "is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -2589,6 +2679,12 @@ "verror": "1.10.0" } }, + "just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, "jwa": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", @@ -2670,6 +2766,12 @@ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, "lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -2942,6 +3044,12 @@ } } }, + "module-not-found-error": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/module-not-found-error/-/module-not-found-error-1.0.1.tgz", + "integrity": "sha1-z4tP9PKWQGdNbN0CsOO8UjwrvcA=", + "dev": true + }, "moment": { "version": "2.29.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", @@ -2981,6 +3089,36 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, + "nise": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.1.tgz", + "integrity": "sha512-yr5kW2THW1AkxVmCnKEh4nbYkJdB3I7LUkiUgOvEkOp414mc2UMaHMA7pjq1nYowhdoJZGwEKGaQVbxfpWj10A==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.8.3", + "@sinonjs/fake-timers": ">=5", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + } + } + }, "node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -3111,6 +3249,12 @@ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -3215,6 +3359,17 @@ "ipaddr.js": "1.9.1" } }, + "proxyquire": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/proxyquire/-/proxyquire-2.1.3.tgz", + "integrity": "sha512-BQWfCqYM+QINd+yawJz23tbBM40VIGXOdDw3X344KcclI/gtBbdWF6SlQ4nK/bYhF9d27KYug9WzljHC6B9Ysg==", + "dev": true, + "requires": { + "fill-keys": "^1.0.2", + "module-not-found-error": "^1.0.1", + "resolve": "^1.11.1" + } + }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -3515,6 +3670,17 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, + "resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "requires": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -3675,6 +3841,31 @@ "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", "optional": true }, + "sinon": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-13.0.1.tgz", + "integrity": "sha512-8yx2wIvkBjIq/MGY1D9h1LMraYW+z1X0mb648KZnKSdvLasvDu7maa0dFaNYdTDczFgbjNw2tOmWdTk9saVfwQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.8.3", + "@sinonjs/fake-timers": "^9.0.0", + "@sinonjs/samsam": "^6.1.1", + "diff": "^5.0.0", + "nise": "^5.1.1", + "supports-color": "^7.2.0" + }, + "dependencies": { + "@sinonjs/fake-timers": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.0.0.tgz", + "integrity": "sha512-+shXA2X7KNP7H7qNbQTJ3SA+NQc0pZDSBrdvFSRwF8sAo/ohw+ZQFD8Moc+gnz51+1eRXtEQBpKWPiQ4jsRC/w==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + } + } + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -3786,6 +3977,12 @@ "has-flag": "^4.0.0" } }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, "ta-json-x": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/ta-json-x/-/ta-json-x-2.5.3.tgz", diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index cf17ae95..94e5ae32 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -9,7 +9,7 @@ "logs": "firebase functions:log", "build": "tsc", "test:run": "mocha --recursive --require ts-node/register", - "test": "npm run test:run2 -- src/**/*.test.ts", + "test": "npm run test:run -- src/**/*.test.ts", "lint": "eslint src/**/*.ts", "scene-typed": "echo \"// npm run scene-typed \n\n\nexport type TSdkScene = \" $(for I in `ls ../../sdk/custom/scenes | cut -d \".\" -f1`; do echo \"'$I' |\"; done) | sed 's/..$/;/' > src/sdk.d.ts", "i18n-typed": "typed-i18next -i src/translation -o src/typings/i18n.d.ts" @@ -31,6 +31,8 @@ "devDependencies": { "@types/chai": "^4.3.0", "@types/mocha": "^9.0.0", + "@types/proxyquire": "^1.3.28", + "@types/sinon": "^10.0.9", "@typescript-eslint/eslint-plugin": "^5.3.1", "@typescript-eslint/parser": "^5.3.1", "chai": "^4.3.6", @@ -38,7 +40,9 @@ "eslint-config-google": "^0.14.0", "firebase-functions-test": "^0.2.0", "mocha": "^9.1.3", + "proxyquire": "^2.1.3", "rimraf": "^3.0.2", + "sinon": "^13.0.1", "ts-node": "^10.4.0", "typed-i18next": "^0.1.2", "typescript": "^4.4.4", diff --git a/webhooks/functions/src/controller/assistant.ts b/webhooks/functions/src/controller/assistant.ts new file mode 100644 index 00000000..8ea4016b --- /dev/null +++ b/webhooks/functions/src/controller/assistant.ts @@ -0,0 +1,18 @@ +import { conversation } from "@assistant/conversation"; +import { PROJECT_ID } from "../constants"; +import { IConversationV3App } from "../type"; + +export const app = conversation({ + verification: PROJECT_ID, + debug: true, +}) as IConversationV3App; + +const appHandle: typeof app.handle = app.handle.bind(app); +app.handle = (path, fn) => { + const ret = appHandle(path, async (conv) => { + + await Promise.resolve(fn({conv})); + + }); + return ret; +} \ No newline at end of file diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index cca0ebf6..c568a752 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -1,25 +1,7 @@ -import { conversation } from "@assistant/conversation"; -import { PROJECT_ID } from "./constants"; -import { IConversationV3App } from "./type"; - -const app = conversation({ - verification: PROJECT_ID, - debug: true, -}) as IConversationV3App; - -const appHandle: typeof app.handle = app.handle.bind(app); -app.handle = (path, fn) => { - const ret = appHandle(path, async (conv) => { - - await Promise.resolve(fn({conv})); - - }); - return ret; -} - +import { app } from "./controller/assistant"; app.handle('main', async ({conv}) => { conv.add('main'); -}); \ No newline at end of file +}); diff --git a/webhooks/functions/src/model/storage.dto.ts b/webhooks/functions/src/model/storage.dto.ts index 9a811f89..6dd03e9a 100644 --- a/webhooks/functions/src/model/storage.dto.ts +++ b/webhooks/functions/src/model/storage.dto.ts @@ -117,7 +117,8 @@ export class StorageDto implements IStorage { const errors = validateSync(storage); if (errors.length) { - bearerToken = bearerToken || typeof data?.bearerToken === 'string' ? data?.bearerToken : undefined; + + bearerToken = typeof data?.bearerToken === 'string' ? data?.bearerToken : bearerToken; if (!bearerToken) { throw new Error('bearerToken is empty'); } diff --git a/webhooks/functions/src/model/storage.model.ts b/webhooks/functions/src/model/storage.model.ts index 162976a6..fcc4c860 100644 --- a/webhooks/functions/src/model/storage.model.ts +++ b/webhooks/functions/src/model/storage.model.ts @@ -25,14 +25,13 @@ export class StorageModel { public static async create(bearerToken: string) { - ok(""); - let store: StorageDto; try { const data = await pull(bearerToken); + store = StorageDto.create(data, bearerToken); } catch (e) { - console.error("StorageModel Create Error", e); + console.error("StorageModel Create", e); store = StorageDto.create(undefined, bearerToken); } return new StorageModel(bearerToken, store); diff --git a/webhooks/functions/src/model/storage.test.ts b/webhooks/functions/src/model/storage.test.ts index da463611..fc83cc3d 100644 --- a/webhooks/functions/src/model/storage.test.ts +++ b/webhooks/functions/src/model/storage.test.ts @@ -4,6 +4,11 @@ import * as assert from 'assert'; import {classToPlain} from 'class-transformer'; import {inspect} from 'util'; import * as chai from 'chai'; +// import { StorageModel } from './storage.model'; +import * as sinon from 'sinon'; +import * as proxyquire from 'proxyquire'; + +import { StorageModel } from './storage.model'; chai.should(); @@ -238,9 +243,55 @@ describe('storage DTO', () => { describe('storage Model', () => { - done(); - it('create a storeModel', async (done) => { + const freshData = { + dbVersion: 1, + bearerToken: 'test', + player: { + current: { + playing: false, + }, + history: { + + }, + }, + }; + + let data: StorageModel; + const pull = sinon.stub().resolves({}); + const push = sinon.stub(); + + beforeEach(async() => { + + const { StorageModel: _storageModel } = proxyquire("./storage.model", { + './database': { + pull, + push, + } + }) as { StorageModel: StorageModel & { create: typeof StorageModel.create } }; + + data = await _storageModel.create("test"); }) + it('create a storeModel', async () => { + + console.log(JSON.stringify(data.store.extract(), null, 4)); + + assert.deepEqual(data.store.extract(), freshData); + + data.store.should.instanceOf(StorageDto); + data.store.extract().should.to.deep.eq(freshData); + pull.calledOnce.should.eq(true); + + }) + + it('push store', async () => { + + data.save(); + + push.calledOnce.should.eq(true); + push.args.should.to.deep.equal([['test', freshData]]); + + }); + }); \ No newline at end of file From 88624de87370666d1388cd93677c84017be97a89 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 3 Feb 2022 15:09:30 +0100 Subject: [PATCH 088/180] feature: create the machine --- webhooks/functions/package.json | 3 +- webhooks/functions/src/controller/Machine.ts | 56 +++++++++++++++++++ .../functions/src/controller/assistant.ts | 28 ++++++++-- .../functions/src/controller/handler/index.ts | 4 ++ .../functions/src/controller/handler/main.ts | 7 +++ webhooks/functions/src/translation/index.ts | 5 +- webhooks/functions/src/type.ts | 13 ++++- .../functions/src/typings/sdkHandler.d.ts | 4 ++ 8 files changed, 107 insertions(+), 13 deletions(-) create mode 100644 webhooks/functions/src/controller/Machine.ts create mode 100644 webhooks/functions/src/controller/handler/index.ts create mode 100644 webhooks/functions/src/controller/handler/main.ts create mode 100644 webhooks/functions/src/typings/sdkHandler.d.ts diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index 94e5ae32..2b7ff4e3 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -11,7 +11,8 @@ "test:run": "mocha --recursive --require ts-node/register", "test": "npm run test:run -- src/**/*.test.ts", "lint": "eslint src/**/*.ts", - "scene-typed": "echo \"// npm run scene-typed \n\n\nexport type TSdkScene = \" $(for I in `ls ../../sdk/custom/scenes | cut -d \".\" -f1`; do echo \"'$I' |\"; done) | sed 's/..$/;/' > src/sdk.d.ts", + "scene-typed": "echo \"// npm run scene-typed \n\n\nexport type TSdkScene = \" $(for I in `ls ../../sdk/custom/scenes | cut -d \".\" -f1`; do echo \"'$I' |\"; done) | sed 's/..$/;/' > src/typings/sdkScene.d.ts", + "handler-typed": "echo \"// npm run handler-typed \n\n\nexport type TSdkHandler = \" $(for I in `cat ../../sdk/webhooks/ActionsOnGoogleFulfillment.yaml | grep \"name:\" | cut -d' ' -s -f3`; do echo \"'$I' |\"; done) | sed 's/..$/;/' > src/typings/sdkHandler.d.ts", "i18n-typed": "typed-i18next -i src/translation -o src/typings/i18n.d.ts" }, "engines": { diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts new file mode 100644 index 00000000..371193f5 --- /dev/null +++ b/webhooks/functions/src/controller/Machine.ts @@ -0,0 +1,56 @@ +import { ok } from "assert"; +import { StorageModel } from "../model/storage.model"; +import { i18n, TI18n, TI18nKey } from "../translation"; +import { IConversationV3 } from "../type"; + +export class Machine { + + private _conv: IConversationV3; + private _i18n: TI18n; + private _model: StorageModel | undefined; + + private _sayAcc: string; + + constructor(conv: IConversationV3) { + ok(conv); + + this._i18n = i18n; + this._model = undefined; + this._conv = conv; + + this._sayAcc = ""; + } + + public async begin({ + bearerToken + }: { + bearerToken?: string + }) { + + console.info("Machine BEGIN"); + + if (typeof bearerToken === "string") { + this._model = await StorageModel.create(bearerToken); + } + } + + public async end() { + + console.info("Machine END"); + + if (this._model) { + await this._model.save(); + } + + if (this._sayAcc) { + console.info("SAY: ", this._sayAcc); + this._conv.add(this._sayAcc); + } + + } + + public async say(key: TI18nKey, options?: object) { + + this._sayAcc += this._i18n.t(key, options); + } +} \ No newline at end of file diff --git a/webhooks/functions/src/controller/assistant.ts b/webhooks/functions/src/controller/assistant.ts index 8ea4016b..49ec96b7 100644 --- a/webhooks/functions/src/controller/assistant.ts +++ b/webhooks/functions/src/controller/assistant.ts @@ -1,18 +1,34 @@ import { conversation } from "@assistant/conversation"; import { PROJECT_ID } from "../constants"; -import { IConversationV3App } from "../type"; +import { IConversationV3App, THandlerFn } from "../type"; +import { TSdkHandler } from "../typings/sdkHandler"; +import { Machine } from "./Machine"; export const app = conversation({ verification: PROJECT_ID, debug: true, }) as IConversationV3App; -const appHandle: typeof app.handle = app.handle.bind(app); -app.handle = (path, fn) => { - const ret = appHandle(path, async (conv) => { +app.catch((conv, error) => { - await Promise.resolve(fn({conv})); + console.error('APP CATCH ERROR', error); + if (conv.scene.next) + conv.scene.next.name = conv.scene.name; // loop +}); + +// app.middleware((_conv, _framework) => {}); + +export const handle = (path: TSdkHandler, fn: THandlerFn) => { + + app.handle(path, async (conv) => { + const machine = new Machine(conv); + + const bearerToken = conv.user.params.bearerToken; + await machine.begin({ bearerToken }); + + await Promise.resolve(fn(machine)); + + await machine.end(); }); - return ret; } \ No newline at end of file diff --git a/webhooks/functions/src/controller/handler/index.ts b/webhooks/functions/src/controller/handler/index.ts new file mode 100644 index 00000000..4b192858 --- /dev/null +++ b/webhooks/functions/src/controller/handler/index.ts @@ -0,0 +1,4 @@ +import { handle } from "../assistant"; +import { main } from "./main"; + +handle('main', main); \ No newline at end of file diff --git a/webhooks/functions/src/controller/handler/main.ts b/webhooks/functions/src/controller/handler/main.ts new file mode 100644 index 00000000..f5e9f8e6 --- /dev/null +++ b/webhooks/functions/src/controller/handler/main.ts @@ -0,0 +1,7 @@ +import { TMachine } from "../../type"; + +export const main = (machine: TMachine) => { + + machine.say("hello world"); + +} \ No newline at end of file diff --git a/webhooks/functions/src/translation/index.ts b/webhooks/functions/src/translation/index.ts index 8883b5d5..9122c2c1 100644 --- a/webhooks/functions/src/translation/index.ts +++ b/webhooks/functions/src/translation/index.ts @@ -14,6 +14,5 @@ i18next.init({ export type TI18nKey = Translations['keys']['fr']; -export const i18n = i18next; - -export const t = i18n.t as (key: TI18nKey, options? : object) => any; +export type TI18n = typeof i18next & {t: (key: TI18nKey, options? : object) => any}; +export const i18n: TI18n = i18next; diff --git a/webhooks/functions/src/type.ts b/webhooks/functions/src/type.ts index e45e58a6..3826a425 100644 --- a/webhooks/functions/src/type.ts +++ b/webhooks/functions/src/type.ts @@ -1,5 +1,6 @@ import { ConversationV3, ConversationV3App } from "@assistant/conversation"; import { Media } from "@assistant/conversation/dist/api/schema"; +import { Machine } from "./controller/Machine"; import { TI18nKey } from "./translation"; export enum MediaType { @@ -16,9 +17,15 @@ export enum OptionalMediaControl { export type TPromptItem = TI18nKey | {[k: string]: any} | Media; //PromtItem type from @assistant/conversation -export interface IConversationWithParams extends ConversationV3 { +export interface IConversationV3 extends ConversationV3 { +} + +export interface IConversationWithParams extends IConversationV3 { } export interface IConversationV3App extends ConversationV3App { - handle: (path: string, fn: (obj: any) => any) => this; -} \ No newline at end of file +} + +export type TMachine = Machine; + +export type THandlerFn = (machine: TMachine) => TMachine | undefined | void; \ No newline at end of file diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts new file mode 100644 index 00000000..bc081545 --- /dev/null +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -0,0 +1,4 @@ +// npm run handler-typed ; + + +export type TSdkHandler = 'cancel' | 'media_status' | 'player' | 'ask_to_resume_listening_at_last_offset' | 'main' | 'home_lvl1' | 'home_lvl1__intent__enter_member_space_lvl1' | 'home_lvl1__intent__resume_listening_player' | 'home_lvl1__intent__get_info_association_lvl1' | 'home_lvl1__intent__listen_audiobook_lvl1' | 'home_members_lvl2' | 'home_members_lvl2__intent__listen_audiobook_lvl2' | 'home_members_lvl2__intent__resume_audiobook_lvl2' | 'home_members__intent__selection_audiobook_lvl2' | 'selection_lvl3' | 'selection_lvl3__intent__selection_thematic_list_lvl3' | 'selection_lvl3__intent__selection_genre_lvl3' | 'selection_lvl3__intent__selection_my_list_lvl3' | 'ask_to_resume_listening_at_last_offset__intent__yes' | 'player__intent__resume_listening_player' | 'player__intent__remaining_time_player' | 'search' | 'search__slot__query' | 'search__intent__resume_listening_player' | 'test_player_sdk' | 'test_setup_sdk' | 'test_webhook' | 'ask_to_resume_listening_at_last_offset__intent__no' | 'player__intent__menu' | 'select_publication__slot__number' | 'select_publication__intent__resume_listening_player' | 'select_publication' | 'select_publication__intent__stop' | 'select_publication__intent__next' | 'select_group' | 'select_group__slot__number' | 'select_group__intent__stop' | 'selection_lvl3__intent__selection_all_publication_lvl3' | 'select_publication__intent__repeat' | 'select_group__intent__menu' | 'player_toc' | 'player_toc__intent__repeat' | 'player_toc__intent__next' | 'player_toc__intent__resume_listening_player' | 'player_toc__slot__number' | 'player__intent__listen_toc'; From 9ffe972d07c9f6bb8854c3689eba311cad30d157 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 3 Feb 2022 15:14:55 +0100 Subject: [PATCH 089/180] lint --- webhooks/functions/package.json | 5 ++- webhooks/functions/src/controller/Machine.ts | 27 +++++------- .../functions/src/controller/assistant.ts | 21 +++++----- webhooks/functions/src/model/storage.dto.ts | 1 - webhooks/functions/src/model/storage.model.ts | 17 +++----- webhooks/functions/src/model/storage.test.ts | 41 ++++++++----------- .../functions/src/typings/sdkHandler.d.ts | 2 +- 7 files changed, 48 insertions(+), 66 deletions(-) diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index 2b7ff4e3..7d190f2e 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -11,8 +11,9 @@ "test:run": "mocha --recursive --require ts-node/register", "test": "npm run test:run -- src/**/*.test.ts", "lint": "eslint src/**/*.ts", - "scene-typed": "echo \"// npm run scene-typed \n\n\nexport type TSdkScene = \" $(for I in `ls ../../sdk/custom/scenes | cut -d \".\" -f1`; do echo \"'$I' |\"; done) | sed 's/..$/;/' > src/typings/sdkScene.d.ts", - "handler-typed": "echo \"// npm run handler-typed \n\n\nexport type TSdkHandler = \" $(for I in `cat ../../sdk/webhooks/ActionsOnGoogleFulfillment.yaml | grep \"name:\" | cut -d' ' -s -f3`; do echo \"'$I' |\"; done) | sed 's/..$/;/' > src/typings/sdkHandler.d.ts", + "lint:fix": "eslint src/**/*.ts --fix", + "scene-typed": "echo \"// npm run scene-typed \n\n\nexport type TSdkScene = \"$(for I in `ls ../../sdk/custom/scenes | cut -d \".\" -f1`; do echo \"'$I' |\"; done) | sed 's/..$/;/' > src/typings/sdkScene.d.ts", + "handler-typed": "echo \"// npm run handler-typed \n\n\nexport type TSdkHandler = \"$(for I in `cat ../../sdk/webhooks/ActionsOnGoogleFulfillment.yaml | grep \"name:\" | cut -d' ' -s -f3`; do echo \"'$I' |\"; done) | sed 's/..$/;/' > src/typings/sdkHandler.d.ts", "i18n-typed": "typed-i18next -i src/translation -o src/typings/i18n.d.ts" }, "engines": { diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 371193f5..4750467e 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -1,10 +1,9 @@ -import { ok } from "assert"; -import { StorageModel } from "../model/storage.model"; -import { i18n, TI18n, TI18nKey } from "../translation"; -import { IConversationV3 } from "../type"; +import {ok} from 'assert'; +import {StorageModel} from '../model/storage.model'; +import {i18n, TI18n, TI18nKey} from '../translation'; +import {IConversationV3} from '../type'; export class Machine { - private _conv: IConversationV3; private _i18n: TI18n; private _model: StorageModel | undefined; @@ -18,39 +17,35 @@ export class Machine { this._model = undefined; this._conv = conv; - this._sayAcc = ""; + this._sayAcc = ''; } public async begin({ - bearerToken + bearerToken, }: { bearerToken?: string }) { + console.info('Machine BEGIN'); - console.info("Machine BEGIN"); - - if (typeof bearerToken === "string") { + if (typeof bearerToken === 'string') { this._model = await StorageModel.create(bearerToken); } } public async end() { - - console.info("Machine END"); + console.info('Machine END'); if (this._model) { await this._model.save(); } if (this._sayAcc) { - console.info("SAY: ", this._sayAcc); + console.info('SAY: ', this._sayAcc); this._conv.add(this._sayAcc); } - } public async say(key: TI18nKey, options?: object) { - this._sayAcc += this._i18n.t(key, options); } -} \ No newline at end of file +} diff --git a/webhooks/functions/src/controller/assistant.ts b/webhooks/functions/src/controller/assistant.ts index 49ec96b7..3828e724 100644 --- a/webhooks/functions/src/controller/assistant.ts +++ b/webhooks/functions/src/controller/assistant.ts @@ -1,8 +1,8 @@ -import { conversation } from "@assistant/conversation"; -import { PROJECT_ID } from "../constants"; -import { IConversationV3App, THandlerFn } from "../type"; -import { TSdkHandler } from "../typings/sdkHandler"; -import { Machine } from "./Machine"; +import {conversation} from '@assistant/conversation'; +import {PROJECT_ID} from '../constants'; +import {IConversationV3App, THandlerFn} from '../type'; +import {TSdkHandler} from '../typings/sdkHandler'; +import {Machine} from './Machine'; export const app = conversation({ verification: PROJECT_ID, @@ -10,25 +10,24 @@ export const app = conversation({ }) as IConversationV3App; app.catch((conv, error) => { - console.error('APP CATCH ERROR', error); - if (conv.scene.next) - conv.scene.next.name = conv.scene.name; // loop + if (conv.scene.next) { + conv.scene.next.name = conv.scene.name; + } // loop }); // app.middleware((_conv, _framework) => {}); export const handle = (path: TSdkHandler, fn: THandlerFn) => { - app.handle(path, async (conv) => { const machine = new Machine(conv); const bearerToken = conv.user.params.bearerToken; - await machine.begin({ bearerToken }); + await machine.begin({bearerToken}); await Promise.resolve(fn(machine)); await machine.end(); }); -} \ No newline at end of file +}; diff --git a/webhooks/functions/src/model/storage.dto.ts b/webhooks/functions/src/model/storage.dto.ts index 6dd03e9a..976238c2 100644 --- a/webhooks/functions/src/model/storage.dto.ts +++ b/webhooks/functions/src/model/storage.dto.ts @@ -117,7 +117,6 @@ export class StorageDto implements IStorage { const errors = validateSync(storage); if (errors.length) { - bearerToken = typeof data?.bearerToken === 'string' ? data?.bearerToken : bearerToken; if (!bearerToken) { throw new Error('bearerToken is empty'); diff --git a/webhooks/functions/src/model/storage.model.ts b/webhooks/functions/src/model/storage.model.ts index fcc4c860..2e7a2909 100644 --- a/webhooks/functions/src/model/storage.model.ts +++ b/webhooks/functions/src/model/storage.model.ts @@ -1,17 +1,15 @@ -import { ok } from 'assert'; -import { pull, push } from './database'; -import { StorageDto } from './storage.dto'; +import {ok} from 'assert'; +import {pull, push} from './database'; +import {StorageDto} from './storage.dto'; export class StorageModel { - private _bearer: string; private _storage: StorageDto; private static _singleton: boolean; constructor(bearerToken: string, store: StorageDto) { - if (StorageModel._singleton) { - throw new Error("already instancied"); + throw new Error('already instancied'); } ok(bearerToken); @@ -24,21 +22,19 @@ export class StorageModel { } public static async create(bearerToken: string) { - let store: StorageDto; try { const data = await pull(bearerToken); store = StorageDto.create(data, bearerToken); } catch (e) { - console.error("StorageModel Create", e); + console.error('StorageModel Create', e); store = StorageDto.create(undefined, bearerToken); } return new StorageModel(bearerToken, store); } public async save() { - const data = this.store.extract(); await push(this._bearer, data); } @@ -46,5 +42,4 @@ export class StorageModel { get store() { return this._storage; } - -} \ No newline at end of file +} diff --git a/webhooks/functions/src/model/storage.test.ts b/webhooks/functions/src/model/storage.test.ts index fc83cc3d..ce9c1468 100644 --- a/webhooks/functions/src/model/storage.test.ts +++ b/webhooks/functions/src/model/storage.test.ts @@ -8,7 +8,7 @@ import * as chai from 'chai'; import * as sinon from 'sinon'; import * as proxyquire from 'proxyquire'; -import { StorageModel } from './storage.model'; +import {StorageModel} from './storage.model'; chai.should(); @@ -243,38 +243,35 @@ describe('storage DTO', () => { describe('storage Model', () => { - const freshData = { - dbVersion: 1, - bearerToken: 'test', - player: { - current: { - playing: false, - }, - history: { + dbVersion: 1, + bearerToken: 'test', + player: { + current: { + playing: false, + }, + history: { - }, }, - }; + }, + }; let data: StorageModel; const pull = sinon.stub().resolves({}); const push = sinon.stub(); - beforeEach(async() => { - - const { StorageModel: _storageModel } = proxyquire("./storage.model", { + beforeEach(async () => { + const {StorageModel: _storageModel} = proxyquire('./storage.model', { './database': { pull, push, - } + }, }) as { StorageModel: StorageModel & { create: typeof StorageModel.create } }; - data = await _storageModel.create("test"); - }) + data = await _storageModel.create('test'); + }); it('create a storeModel', async () => { - console.log(JSON.stringify(data.store.extract(), null, 4)); assert.deepEqual(data.store.extract(), freshData); @@ -282,16 +279,12 @@ describe('storage Model', () => { data.store.should.instanceOf(StorageDto); data.store.extract().should.to.deep.eq(freshData); pull.calledOnce.should.eq(true); - - }) + }); it('push store', async () => { - data.save(); push.calledOnce.should.eq(true); push.args.should.to.deep.equal([['test', freshData]]); - }); - -}); \ No newline at end of file +}); diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index bc081545..69f02ae3 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'cancel' | 'media_status' | 'player' | 'ask_to_resume_listening_at_last_offset' | 'main' | 'home_lvl1' | 'home_lvl1__intent__enter_member_space_lvl1' | 'home_lvl1__intent__resume_listening_player' | 'home_lvl1__intent__get_info_association_lvl1' | 'home_lvl1__intent__listen_audiobook_lvl1' | 'home_members_lvl2' | 'home_members_lvl2__intent__listen_audiobook_lvl2' | 'home_members_lvl2__intent__resume_audiobook_lvl2' | 'home_members__intent__selection_audiobook_lvl2' | 'selection_lvl3' | 'selection_lvl3__intent__selection_thematic_list_lvl3' | 'selection_lvl3__intent__selection_genre_lvl3' | 'selection_lvl3__intent__selection_my_list_lvl3' | 'ask_to_resume_listening_at_last_offset__intent__yes' | 'player__intent__resume_listening_player' | 'player__intent__remaining_time_player' | 'search' | 'search__slot__query' | 'search__intent__resume_listening_player' | 'test_player_sdk' | 'test_setup_sdk' | 'test_webhook' | 'ask_to_resume_listening_at_last_offset__intent__no' | 'player__intent__menu' | 'select_publication__slot__number' | 'select_publication__intent__resume_listening_player' | 'select_publication' | 'select_publication__intent__stop' | 'select_publication__intent__next' | 'select_group' | 'select_group__slot__number' | 'select_group__intent__stop' | 'selection_lvl3__intent__selection_all_publication_lvl3' | 'select_publication__intent__repeat' | 'select_group__intent__menu' | 'player_toc' | 'player_toc__intent__repeat' | 'player_toc__intent__next' | 'player_toc__intent__resume_listening_player' | 'player_toc__slot__number' | 'player__intent__listen_toc'; +export type TSdkHandler = 'cancel' | 'media_status' | 'player' | 'ask_to_resume_listening_at_last_offset' | 'main' | 'home_lvl1' | 'home_lvl1__intent__enter_member_space_lvl1' | 'home_lvl1__intent__resume_listening_player' | 'home_lvl1__intent__get_info_association_lvl1' | 'home_lvl1__intent__listen_audiobook_lvl1' | 'home_members_lvl2' | 'home_members_lvl2__intent__listen_audiobook_lvl2' | 'home_members_lvl2__intent__resume_audiobook_lvl2' | 'home_members__intent__selection_audiobook_lvl2' | 'selection_lvl3' | 'selection_lvl3__intent__selection_thematic_list_lvl3' | 'selection_lvl3__intent__selection_genre_lvl3' | 'selection_lvl3__intent__selection_my_list_lvl3' | 'ask_to_resume_listening_at_last_offset__intent__yes' | 'player__intent__resume_listening_player' | 'player__intent__remaining_time_player' | 'search' | 'search__slot__query' | 'search__intent__resume_listening_player' | 'test_player_sdk' | 'test_setup_sdk' | 'test_webhook' | 'ask_to_resume_listening_at_last_offset__intent__no' | 'player__intent__menu' | 'select_publication__slot__number' | 'select_publication__intent__resume_listening_player' | 'select_publication' | 'select_publication__intent__stop' | 'select_publication__intent__next' | 'select_group' | 'select_group__slot__number' | 'select_group__intent__stop' | 'selection_lvl3__intent__selection_all_publication_lvl3' | 'select_publication__intent__repeat' | 'select_group__intent__menu' | 'player_toc' | 'player_toc__intent__repeat' | 'player_toc__intent__next' | 'player_toc__intent__resume_listening_player' | 'player_toc__slot__number' | 'player__intent__listen_toc'; From 6c0aff2303c629d2409803227d3a67426120b64d Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 3 Feb 2022 15:55:19 +0100 Subject: [PATCH 090/180] feat: main handler --- sdk/custom/global/actions.intent.CANCEL.yaml | 9 ++++ sdk/custom/global/actions.intent.MAIN.yaml | 2 + .../global/actions.intent.NO_INPUT_1.yaml | 7 +++ .../global/actions.intent.NO_INPUT_2.yaml | 7 +++ .../global/actions.intent.NO_INPUT_FINAL.yaml | 8 ++++ .../global/actions.intent.NO_MATCH_1.yaml | 7 +++ .../global/actions.intent.NO_MATCH_2.yaml | 7 +++ .../global/actions.intent.NO_MATCH_FINAL.yaml | 8 ++++ sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 44 ------------------- webhooks/functions/src/constants.ts | 6 ++- webhooks/functions/src/controller/Machine.ts | 2 +- .../functions/src/controller/handler/main.ts | 5 ++- webhooks/functions/src/translation/en/en.json | 9 ++++ webhooks/functions/src/translation/index.ts | 2 +- webhooks/functions/src/typings/i18n.d.ts | 2 + 15 files changed, 77 insertions(+), 48 deletions(-) create mode 100644 sdk/custom/global/actions.intent.CANCEL.yaml create mode 100644 sdk/custom/global/actions.intent.MAIN.yaml create mode 100644 sdk/custom/global/actions.intent.NO_INPUT_1.yaml create mode 100644 sdk/custom/global/actions.intent.NO_INPUT_2.yaml create mode 100644 sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml create mode 100644 sdk/custom/global/actions.intent.NO_MATCH_1.yaml create mode 100644 sdk/custom/global/actions.intent.NO_MATCH_2.yaml create mode 100644 sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml create mode 100644 webhooks/functions/src/translation/en/en.json diff --git a/sdk/custom/global/actions.intent.CANCEL.yaml b/sdk/custom/global/actions.intent.CANCEL.yaml new file mode 100644 index 00000000..22c095fb --- /dev/null +++ b/sdk/custom/global/actions.intent.CANCEL.yaml @@ -0,0 +1,9 @@ +handler: + staticPrompt: + candidates: + - promptResponse: + firstSimple: + variants: + - speech: Au revoir et a bientôt + webhookHandler: cancel +transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/custom/global/actions.intent.MAIN.yaml b/sdk/custom/global/actions.intent.MAIN.yaml new file mode 100644 index 00000000..c43ab2e2 --- /dev/null +++ b/sdk/custom/global/actions.intent.MAIN.yaml @@ -0,0 +1,2 @@ +handler: + webhookHandler: main diff --git a/sdk/custom/global/actions.intent.NO_INPUT_1.yaml b/sdk/custom/global/actions.intent.NO_INPUT_1.yaml new file mode 100644 index 00000000..de975f82 --- /dev/null +++ b/sdk/custom/global/actions.intent.NO_INPUT_1.yaml @@ -0,0 +1,7 @@ +handler: + staticPrompt: + candidates: + - promptResponse: + firstSimple: + variants: + - speech: je n'ai pas entendu. Que voulez-vous dire ? diff --git a/sdk/custom/global/actions.intent.NO_INPUT_2.yaml b/sdk/custom/global/actions.intent.NO_INPUT_2.yaml new file mode 100644 index 00000000..59e57245 --- /dev/null +++ b/sdk/custom/global/actions.intent.NO_INPUT_2.yaml @@ -0,0 +1,7 @@ +handler: + staticPrompt: + candidates: + - promptResponse: + firstSimple: + variants: + - speech: Que dite-vous ? diff --git a/sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml b/sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml new file mode 100644 index 00000000..63087279 --- /dev/null +++ b/sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml @@ -0,0 +1,8 @@ +handler: + staticPrompt: + candidates: + - promptResponse: + firstSimple: + variants: + - speech: Je quitte l'application +transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/custom/global/actions.intent.NO_MATCH_1.yaml b/sdk/custom/global/actions.intent.NO_MATCH_1.yaml new file mode 100644 index 00000000..166efc70 --- /dev/null +++ b/sdk/custom/global/actions.intent.NO_MATCH_1.yaml @@ -0,0 +1,7 @@ +handler: + staticPrompt: + candidates: + - promptResponse: + firstSimple: + variants: + - speech: je n'ai pas compris. Que voulez-vous dire ? diff --git a/sdk/custom/global/actions.intent.NO_MATCH_2.yaml b/sdk/custom/global/actions.intent.NO_MATCH_2.yaml new file mode 100644 index 00000000..deda0dc7 --- /dev/null +++ b/sdk/custom/global/actions.intent.NO_MATCH_2.yaml @@ -0,0 +1,7 @@ +handler: + staticPrompt: + candidates: + - promptResponse: + firstSimple: + variants: + - speech: je n'ai vraiment pas compris. Que voulez-vous dire ? diff --git a/sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml b/sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml new file mode 100644 index 00000000..2f8cf92a --- /dev/null +++ b/sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml @@ -0,0 +1,8 @@ +handler: + staticPrompt: + candidates: + - promptResponse: + firstSimple: + variants: + - speech: malheureusement je m'en vais, je ne comprend pas +transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index e69c4449..12a5b47c 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -1,50 +1,6 @@ handlers: - name: cancel -- name: media_status -- name: player -- name: ask_to_resume_listening_at_last_offset - name: main -- name: home_lvl1 -- name: home_lvl1__intent__enter_member_space_lvl1 -- name: home_lvl1__intent__resume_listening_player -- name: home_lvl1__intent__get_info_association_lvl1 -- name: home_lvl1__intent__listen_audiobook_lvl1 -- name: home_members_lvl2 -- name: home_members_lvl2__intent__listen_audiobook_lvl2 -- name: home_members_lvl2__intent__resume_audiobook_lvl2 -- name: home_members__intent__selection_audiobook_lvl2 -- name: selection_lvl3 -- name: selection_lvl3__intent__selection_thematic_list_lvl3 -- name: selection_lvl3__intent__selection_genre_lvl3 -- name: selection_lvl3__intent__selection_my_list_lvl3 -- name: ask_to_resume_listening_at_last_offset__intent__yes -- name: player__intent__resume_listening_player -- name: player__intent__remaining_time_player -- name: search -- name: search__slot__query -- name: search__intent__resume_listening_player -- name: test_player_sdk -- name: test_setup_sdk -- name: test_webhook -- name: ask_to_resume_listening_at_last_offset__intent__no -- name: player__intent__menu -- name: select_publication__slot__number -- name: select_publication__intent__resume_listening_player -- name: select_publication -- name: select_publication__intent__stop -- name: select_publication__intent__next -- name: select_group -- name: select_group__slot__number -- name: select_group__intent__stop -- name: selection_lvl3__intent__selection_all_publication_lvl3 -- name: select_publication__intent__repeat -- name: select_group__intent__menu -- name: player_toc -- name: player_toc__intent__repeat -- name: player_toc__intent__next -- name: player_toc__intent__resume_listening_player -- name: player_toc__slot__number -- name: player__intent__listen_toc httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/constants.ts b/webhooks/functions/src/constants.ts index b846e483..a565c27f 100644 --- a/webhooks/functions/src/constants.ts +++ b/webhooks/functions/src/constants.ts @@ -1,4 +1,6 @@ +export const NAME = "EDRLAB"; + export const API_BASE_URL = "https://storage.googleapis.com/audiobook_edrlab/feed.json"; export const ALL_PUBLICATION_LIST_URL = "https://storage.googleapis.com/audiobook_edrlab/navigation/all.json"; @@ -6,7 +8,9 @@ export const SELECTION_URL = 'https://storage.googleapis.com/audiobook_edrlab/gr export const SEARCH_URL = 'https://europe-west1-audiobooks-a6348.cloudfunctions.net/indexer?url=https://storage.googleapis.com/audiobook_edrlab/navigation/all.json&query={query}'; export const THEMATIC_LIST_URL = 'https://storage.googleapis.com/audiobook_edrlab/navigation/thematic_list.json'; export const GENRE_LIST_URL = 'https://storage.googleapis.com/audiobook_edrlab/navigation/genre_list.json'; -export const DEFAULT_LANGUAGE: TLang = 'fr'; +export const DEFAULT_LANGUAGE: TDefaultLanguage = 'en'; + +export type TDefaultLanguage = Extract; export const PADDING = 5; diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 4750467e..b4978269 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -46,6 +46,6 @@ export class Machine { } public async say(key: TI18nKey, options?: object) { - this._sayAcc += this._i18n.t(key, options); + this._sayAcc += this._i18n.t(key, options) + "\n"; } } diff --git a/webhooks/functions/src/controller/handler/main.ts b/webhooks/functions/src/controller/handler/main.ts index f5e9f8e6..8af39e41 100644 --- a/webhooks/functions/src/controller/handler/main.ts +++ b/webhooks/functions/src/controller/handler/main.ts @@ -1,7 +1,10 @@ +import { NAME } from "../../constants"; import { TMachine } from "../../type"; export const main = (machine: TMachine) => { - machine.say("hello world"); + machine.say("main.welcome.1", { name: NAME}); + machine.say("main.welcome.2", { name: NAME}); + machine.say("main.welcome.3"); } \ No newline at end of file diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json new file mode 100644 index 00000000..fc514cf1 --- /dev/null +++ b/webhooks/functions/src/translation/en/en.json @@ -0,0 +1,9 @@ +{ + "main": { + "welcome": { + "1": "Welcome to {{- name}} Library!", + "2": "To fully enjoy your audiobooks and access your personal bookshelf, you will need to link your {{- name}} account.", + "3": "Would you like to do so now ?" + } + } +} \ No newline at end of file diff --git a/webhooks/functions/src/translation/index.ts b/webhooks/functions/src/translation/index.ts index 9122c2c1..2a21fa63 100644 --- a/webhooks/functions/src/translation/index.ts +++ b/webhooks/functions/src/translation/index.ts @@ -12,7 +12,7 @@ i18next.init({ fallbackLng: DEFAULT_LANGUAGE, }); -export type TI18nKey = Translations['keys']['fr']; +export type TI18nKey = Translations['keys'][typeof DEFAULT_LANGUAGE]; export type TI18n = typeof i18next & {t: (key: TI18nKey, options? : object) => any}; export const i18n: TI18n = i18next; diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index 04cbffa8..a08bec0d 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,9 +3,11 @@ export interface Translations { keys: { + "en": "main.welcome.1" | "main.welcome.2" | "main.welcome.3", "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { + "en": "en:main.welcome.1" | "en:main.welcome.2" | "en:main.welcome.3", "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } From c5e0c63ebf0c0f323edb8a2325104114e5bb82c2 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Fri, 4 Feb 2022 15:13:45 +0100 Subject: [PATCH 091/180] feature: express test works --- webhooks/functions/package-lock.json | 35 +++ webhooks/functions/package.json | 2 + webhooks/functions/src/controller/Machine.ts | 14 +- .../functions/src/controller/assistant.ts | 74 +++++-- .../functions/src/controller/handler/index.ts | 7 +- webhooks/functions/src/index.ts | 17 +- webhooks/functions/src/sdk/conv.test.ts | 209 ++++++++++++++++++ webhooks/functions/src/sdk/main.test.ts | 76 +++++++ webhooks/functions/src/sdk/utils.test.ts | 20 ++ webhooks/functions/src/translation/index.ts | 4 + 10 files changed, 425 insertions(+), 33 deletions(-) create mode 100644 webhooks/functions/src/sdk/conv.test.ts create mode 100644 webhooks/functions/src/sdk/main.test.ts create mode 100644 webhooks/functions/src/sdk/utils.test.ts diff --git a/webhooks/functions/package-lock.json b/webhooks/functions/package-lock.json index 9fca7a55..b7c26de6 100644 --- a/webhooks/functions/package-lock.json +++ b/webhooks/functions/package-lock.json @@ -1758,6 +1758,15 @@ } } }, + "express-request-mock": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/express-request-mock/-/express-request-mock-3.1.0.tgz", + "integrity": "sha512-Ep1uuqCRUc2nTjwAeaVuviDGPCOU2xIhyVHQoN6+xDc9ANJJY42auiAO0guJTvnyyHY/8Q3/hZWEjHf1eo6hSQ==", + "dev": true, + "requires": { + "node-mocks-http": "^1.9.0" + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -3132,6 +3141,32 @@ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" }, + "node-mocks-http": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-mocks-http/-/node-mocks-http-1.11.0.tgz", + "integrity": "sha512-jS/WzSOcKbOeGrcgKbenZeNhxUNnP36Yw11+hL4TTxQXErGfqYZ+MaYNNvhaTiGIJlzNSqgQkk9j8dSu1YWSuw==", + "dev": true, + "requires": { + "accepts": "^1.3.7", + "content-disposition": "^0.5.3", + "depd": "^1.1.0", + "fresh": "^0.5.2", + "merge-descriptors": "^1.0.1", + "methods": "^1.1.2", + "mime": "^1.3.4", + "parseurl": "^1.3.3", + "range-parser": "^1.2.0", + "type-is": "^1.6.18" + }, + "dependencies": { + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + } + } + }, "node-stream-zip": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.15.0.tgz", diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index 7d190f2e..05fa57d1 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -40,8 +40,10 @@ "chai": "^4.3.6", "eslint": "^8.2.0", "eslint-config-google": "^0.14.0", + "express-request-mock": "^3.1.0", "firebase-functions-test": "^0.2.0", "mocha": "^9.1.3", + "node-mocks-http": "^1.11.0", "proxyquire": "^2.1.3", "rimraf": "^3.0.2", "sinon": "^13.0.1", diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index b4978269..b4b4ef40 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -21,14 +21,20 @@ export class Machine { } public async begin({ - bearerToken, + storageModel, + bearerToken }: { - bearerToken?: string + storageModel?: StorageModel, + bearerToken?: string, }) { console.info('Machine BEGIN'); - if (typeof bearerToken === 'string') { - this._model = await StorageModel.create(bearerToken); + if (storageModel) { + this._model = storageModel; + } else { + if (typeof bearerToken === "string") { + this._model = await StorageModel.create(bearerToken); + } } } diff --git a/webhooks/functions/src/controller/assistant.ts b/webhooks/functions/src/controller/assistant.ts index 3828e724..f25a7bfe 100644 --- a/webhooks/functions/src/controller/assistant.ts +++ b/webhooks/functions/src/controller/assistant.ts @@ -1,33 +1,59 @@ -import {conversation} from '@assistant/conversation'; +import { BaseApp, conversation, ConversationV3, ConversationV3App, OmniHandler } from '@assistant/conversation'; import {PROJECT_ID} from '../constants'; -import {IConversationV3App, THandlerFn} from '../type'; -import {TSdkHandler} from '../typings/sdkHandler'; -import {Machine} from './Machine'; +import { StorageModel } from '../model/storage.model'; +import { IConversationV3App, THandlerFn, TMachine } from '../type'; +import { TSdkHandler } from '../typings/sdkHandler'; +import { Machine } from './Machine'; -export const app = conversation({ - verification: PROJECT_ID, - debug: true, -}) as IConversationV3App; +export class Assistant { -app.catch((conv, error) => { - console.error('APP CATCH ERROR', error); + private _app: OmniHandler & BaseApp & ConversationV3App; + private _storageModel: StorageModel | undefined; + + constructor({ + storageModel + }: { + storageModel?: StorageModel, + }) { - if (conv.scene.next) { - conv.scene.next.name = conv.scene.name; - } // loop -}); + this._app = conversation({ + // verification: PROJECT_ID, + debug: true, + }); -// app.middleware((_conv, _framework) => {}); + this._app.catch((conv, error) => { + console.error('APP CATCH ERROR', error); -export const handle = (path: TSdkHandler, fn: THandlerFn) => { - app.handle(path, async (conv) => { - const machine = new Machine(conv); + if (conv.scene.next) { + conv.scene.next.name = conv.scene.name; + } // loop + }); - const bearerToken = conv.user.params.bearerToken; - await machine.begin({bearerToken}); + if (storageModel) { + this._storageModel = storageModel; + } - await Promise.resolve(fn(machine)); + // app.middleware((_conv, _framework) => {}); + } + + public handle = (path: TSdkHandler, fn: THandlerFn) => { + this._app.handle(path, async (conv) => { + + const machine = new Machine(conv); + + const bearerToken = conv.user.params.bearerToken; + await machine.begin({ bearerToken, storageModel: this._storageModel }); + + await Promise.resolve(fn(machine)); + + await machine.end(); + + // console.log(JSON.stringify(conv, null, 4)); + }); + }; + + public get app() { + return this._app; + } +} - await machine.end(); - }); -}; diff --git a/webhooks/functions/src/controller/handler/index.ts b/webhooks/functions/src/controller/handler/index.ts index 4b192858..d62f3171 100644 --- a/webhooks/functions/src/controller/handler/index.ts +++ b/webhooks/functions/src/controller/handler/index.ts @@ -1,4 +1,7 @@ -import { handle } from "../assistant"; +import { Assistant } from "../Assistant"; import { main } from "./main"; -handle('main', main); \ No newline at end of file +export const handler = (app = new Assistant({})) => { + + app.handle('main', main); +} \ No newline at end of file diff --git a/webhooks/functions/src/index.ts b/webhooks/functions/src/index.ts index c568a752..1580af4e 100644 --- a/webhooks/functions/src/index.ts +++ b/webhooks/functions/src/index.ts @@ -1,7 +1,18 @@ -import { app } from "./controller/assistant"; -app.handle('main', async ({conv}) => { +// class-transformer +import 'reflect-metadata'; - conv.add('main'); +import * as functions from "firebase-functions"; +import { Assistant } from "./controller/Assistant"; +import { handler } from "./controller/handler"; +// import { writeFileSync} from 'fs'; + +exports.ActionsOnGoogleFulfillment = functions.https.onRequest(async (req, res) => { + + const app = new Assistant({}); + + handler(app); + + app.app(req, res); }); diff --git a/webhooks/functions/src/sdk/conv.test.ts b/webhooks/functions/src/sdk/conv.test.ts new file mode 100644 index 00000000..edeea2f0 --- /dev/null +++ b/webhooks/functions/src/sdk/conv.test.ts @@ -0,0 +1,209 @@ + +export const headers = { + "host": "fb9b-89-90-221-249.ngrok.io", + "user-agent": "Google-ActionsOnGoogle/1.0", + "content-length": "755", + "accept-encoding": "gzip, deflate, br", + "content-type": "application/json;charset=UTF-8", + "google-actions-api-version": "3", + "google-assistant-signature": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjllYWEwMjZmNjM1MTU3ZGZhZDUzMmU0MTgzYTZiODIzZDc1MmFkMWQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhdWQiOiJlZHJsYWItMSIsIm5iZiI6MTY0MzkwNTY0OSwiaWF0IjoxNjQzOTA1OTQ5LCJleHAiOjE2NDM5MDYwNjksImp0aSI6ImQwMzQ1NmU3NDk5MWUxNGY0NjAwYjZhZWIxMWUzMzdkZDc2ODJkYjIifQ.gJ3hcEEw0qfUGf7z4WBFee4D9kdxV9kQzjbbhmL17K_nSTnrMISJZyj1DlmmcPragmp6EXWbJ14zTIzmrKPoDbEyx8H4PYG3h6vSGo4tlyB_H69hr0QKRU8fCc5lBQXVMGViuJBAMI9jWP28H2nt7hV0p-_AHayJnEvwSju5ojcd9wAalpTYcJagfdTkT2kvJEh_GeyooZvPZEOnx0vc3laTvrQqdxgP6Sh4wHbJnptj4bUiUirONuFp63C9Y92zkQPDD6tiQ8an475EjI9cys_-KDtXBhfx4Ojo3M0_9jBgpN67aDVk0vOnHYtnXzBg_fZhiM0sLaZRbe49LucHHw", + "x-forwarded-for": "66.249.81.244", + "x-forwarded-proto": "https", + "connection": "close" +}; + +export const request = { + "handler": { + "name": "main" + }, + "intent": { + "name": "actions.intent.MAIN", + "params": {}, + "query": "Parler avec dev edrlab" + }, + "scene": { + "name": "actions.scene.START_CONVERSATION", + "slotFillingStatus": "UNSPECIFIED", + "slots": {} + }, + "session": { + "id": "ABwppHGoBsXu3JLKx1PW4N40zjedGWXq2Ln6bsc9POLhC2rshmkstBG-u7EAq2UZ7tjBRmoMgGc", + "params": {}, + "typeOverrides": [], + "languageCode": "" + }, + "user": { + "locale": "fr-CA", + "params": { + "bearerToken": "" + }, + "accountLinkingStatus": "ACCOUNT_LINKING_STATUS_UNSPECIFIED", + "verificationStatus": "VERIFIED", + "packageEntitlements": [], + "gaiamint": "", + "permissions": [], + "lastSeenTime": "2022-02-03T16:15:10Z" + }, + "home": { + "params": {} + }, + "device": { + "capabilities": [ + "SPEECH", + "RICH_RESPONSE", + "LONG_FORM_AUDIO" + ], + "timeZone": { + "id": "Europe/Paris", + "version": "" + } + } +}; + +export const convRequestInHandle = { + "overwrite": true, + "digested": false, + "request": { + "handler": { + "name": "main" + }, + "intent": { + "name": "actions.intent.MAIN", + "params": {}, + "query": "Parler avec dev edrlab" + }, + "scene": { + "name": "actions.scene.START_CONVERSATION", + "slotFillingStatus": "UNSPECIFIED", + "slots": {} + }, + "session": { + "id": "ABwppHEDTsgFwQdV_QSp5YvBdnevHBjuyCHzGH-6VPE-IOTt9RmVZieVouqECeLyyO4g29pOHPA", + "params": {}, + "typeOverrides": [], + "languageCode": "" + }, + "user": { + "locale": "fr-CA", + "params": { + "bearerToken": "bearer token not defined" + }, + "accountLinkingStatus": "ACCOUNT_LINKING_STATUS_UNSPECIFIED", + "verificationStatus": "VERIFIED", + "packageEntitlements": [], + "gaiamint": "", + "permissions": [], + "lastSeenTime": "2022-02-03T16:03:22Z" + }, + "home": { + "params": {} + }, + "device": { + "capabilities": [ + "SPEECH", + "RICH_RESPONSE", + "LONG_FORM_AUDIO" + ], + "timeZone": { + "id": "Europe/Paris", + "version": "" + } + } + }, + "headers": { + "host": "fb9b-89-90-221-249.ngrok.io", + "user-agent": "Google-ActionsOnGoogle/1.0", + "content-length": "755", + "accept-encoding": "gzip, deflate, br", + "content-type": "application/json;charset=UTF-8", + "google-actions-api-version": "3", + "google-assistant-signature": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjllYWEwMjZmNjM1MTU3ZGZhZDUzMmU0MTgzYTZiODIzZDc1MmFkMWQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhdWQiOiJlZHJsYWItMSIsIm5iZiI6MTY0MzkwMzkwNywiaWF0IjoxNjQzOTA0MjA3LCJleHAiOjE2NDM5MDQzMjcsImp0aSI6ImI2OGJkNDM1YjNmNWM1YWVmZmE3OTIwYjNlY2EwMjU0MTkzYjhiOGMifQ.AMiXPH_4OAjSAD9P1dQ0tHGxgdPp0yiHnPeNlH1h1Lmw2fP4URdKiUz7X8fvgFuhgAkffAo9XPKRPeS5JpCCUmQCvjfE4cej45vyHqCjovEBJxuVFwpbmFcilKAIE2JmGoSlDsbyAJvV0c70HiaOjXtVikPll_mprwveXXU3x6OG4pu0Hqqn9RrsQFIyqQ-p9dU1sVjMvIK-Qhg6KRBKfrirEKIz6dCxVZRdj76jYuPZPsmVeLRfwjt8J0GtFHBlAasJxv02Al8WMw0j6GUeN0GkFnVs_0dupgLV1-v2Zhr5BDiCgjHLbwVWIGsh-_4Jay7kjJ2ouh7ZJNTyfc80kg", + "x-forwarded-for": "66.249.81.235", + "x-forwarded-proto": "https", + "connection": "close" + }, + "handler": { + "name": "main" + }, + "intent": { + "name": "actions.intent.MAIN", + "query": "Parler avec dev edrlab", + "params": {} + }, + "scene": { + "name": "actions.scene.START_CONVERSATION", + "slotFillingStatus": "UNSPECIFIED", + "slots": {}, + "next": {} + }, + "session": { + "id": "ABwppHEDTsgFwQdV_QSp5YvBdnevHBjuyCHzGH-6VPE-IOTt9RmVZieVouqECeLyyO4g29pOHPA", + "params": {}, + "typeOverrides": [], + "languageCode": "" + }, + "user": { + "locale": "fr-CA", + "params": { + "bearerToken": "bearer token not defined" + }, + "accountLinkingStatus": "ACCOUNT_LINKING_STATUS_UNSPECIFIED", + "verificationStatus": "VERIFIED", + "packageEntitlements": [], + "gaiamint": "", + "permissions": [], + "lastSeenTime": "2022-02-03T16:03:22Z" + }, + "device": { + "capabilities": [ + "SPEECH", + "RICH_RESPONSE", + "LONG_FORM_AUDIO" + ], + "currentLocation": {}, + "timeZone": { + "id": "Europe/Paris", + "version": "" + } + }, + "home": { + "params": {} + }, + "expected": {}, + "context": {}, + "prompt": { + "override": false + }, + // "_internal": { + // "promptSet": false, + // "orig": { + // "scene": { + // "name": "actions.scene.START_CONVERSATION", + // "slotFillingStatus": "UNSPECIFIED", + // "slots": {}, + // "next": {} + // }, + // "session": { + // "id": "ABwppHEDTsgFwQdV_QSp5YvBdnevHBjuyCHzGH-6VPE-IOTt9RmVZieVouqECeLyyO4g29pOHPA", + // "params": {}, + // "typeOverrides": [], + // "languageCode": "" + // }, + // "user": { + // "locale": "fr-CA", + // "params": { + // "bearerToken": "bearer token not defined" + // }, + // "accountLinkingStatus": "ACCOUNT_LINKING_STATUS_UNSPECIFIED", + // "verificationStatus": "VERIFIED", + // "packageEntitlements": [], + // "gaiamint": "", + // "permissions": [], + // "lastSeenTime": "2022-02-03T16:03:22Z" + // }, + // "home": { + // "params": {} + // } + // } + // } +}; \ No newline at end of file diff --git a/webhooks/functions/src/sdk/main.test.ts b/webhooks/functions/src/sdk/main.test.ts new file mode 100644 index 00000000..09b8f2ee --- /dev/null +++ b/webhooks/functions/src/sdk/main.test.ts @@ -0,0 +1,76 @@ +import { defaults, shell } from "./utils.test"; +import * as chai from 'chai'; +import * as sinon from 'sinon'; +import { headers, request } from "./conv.test"; +import { Assistant } from "../controller/Assistant"; +import * as httpMocks from 'node-mocks-http'; +import { handler } from "../controller/handler"; +import * as proxyquire from 'proxyquire'; +import { StorageModel } from "../model/storage.model"; +import { document } from "firebase-functions/v1/firestore"; +import { JsonObject } from "@assistant/conversation"; + +chai.should(); + +describe('main handler', () => { + + describe('sdk', () => { + + it('check main scene', (done) => { + + shell('cat custom/global/actions.intent.MAIN.yaml | grep "webhookHandler: main"', (stdout) => { + + stdout.should.to.be.eq(" webhookHandler: main\n"); + + }, done); + + }); +}); + + describe('app', () => { + + it('main', async () => { + + let storageModel: StorageModel; + const pull = sinon.stub().resolves({}); + const push = sinon.stub(); + + const { StorageModel: _storageModel } = proxyquire('../model/storage.model', { + './database': { + pull, + push, + }, + }) as { StorageModel: StorageModel & { create: typeof StorageModel.create } }; + + storageModel = await _storageModel.create('test'); + + const assistant = new Assistant({ storageModel }); + + handler(assistant); + + const req = httpMocks.createRequest({ + body: request, + headers: headers, + method: "POST", + }); + + const res = httpMocks.createResponse({ + eventEmitter: require('events').EventEmitter + }); + + const promise = new Promise((resolve) => res.on('end', () => { + const data = res._getData(); + data.prompt.firstSimple.speech.should.to.be.eq("Welcome to EDRLAB Library!\nTo fully enjoy your audiobooks and access your personal bookshelf, you will need to link your EDRLAB account.\nWould you like to do so now ?\n") + + resolve(); + })); + + assistant.app(req, res); + + return promise; + + }); + + }); + +}); \ No newline at end of file diff --git a/webhooks/functions/src/sdk/utils.test.ts b/webhooks/functions/src/sdk/utils.test.ts new file mode 100644 index 00000000..8e0ca031 --- /dev/null +++ b/webhooks/functions/src/sdk/utils.test.ts @@ -0,0 +1,20 @@ + +// class-transformer +import 'reflect-metadata'; +import { exec } from "child_process"; +export const SDK_PATH = "../../sdk"; + +export const defaults = { + cwd: process.env.PWD + "/" + SDK_PATH, + env: process.env +}; + +export const shell = (s: string, fn: (s: string) => void, done: (...a: any[]) => any) => { + + exec(s, defaults, (err, stdout) => { + + fn(stdout); + + done(err); + }); +} \ No newline at end of file diff --git a/webhooks/functions/src/translation/index.ts b/webhooks/functions/src/translation/index.ts index 2a21fa63..2b4cb5dd 100644 --- a/webhooks/functions/src/translation/index.ts +++ b/webhooks/functions/src/translation/index.ts @@ -1,5 +1,6 @@ import * as i18next from 'i18next'; import * as frTranslation from './fr/fr.json'; +import * as enTranslation from './en/en.json'; import {Translations} from './../typings/i18n'; import {DEFAULT_LANGUAGE} from '../constants'; @@ -8,6 +9,9 @@ i18next.init({ 'fr': { translation: frTranslation, }, + 'en': { + translation: enTranslation, + } }, fallbackLng: DEFAULT_LANGUAGE, }); From 3da456fce2cbcd561b04df00a29a5dee11f3829d Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 7 Feb 2022 13:41:22 +0100 Subject: [PATCH 092/180] test cleaning --- webhooks/functions/src/controller/Machine.ts | 6 +- .../functions/src/controller/assistant.ts | 21 +- webhooks/functions/src/model/storage.test.ts | 21 +- webhooks/functions/src/sdk/conv.test.ts | 384 +++++++++--------- webhooks/functions/src/sdk/main.test.ts | 68 +--- webhooks/functions/src/sdk/utils.test.ts | 20 - webhooks/functions/src/test/utils.test.ts | 77 ++++ webhooks/functions/src/translation/index.ts | 2 +- 8 files changed, 299 insertions(+), 300 deletions(-) delete mode 100644 webhooks/functions/src/sdk/utils.test.ts create mode 100644 webhooks/functions/src/test/utils.test.ts diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index b4b4ef40..2d0664e1 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -22,7 +22,7 @@ export class Machine { public async begin({ storageModel, - bearerToken + bearerToken, }: { storageModel?: StorageModel, bearerToken?: string, @@ -32,7 +32,7 @@ export class Machine { if (storageModel) { this._model = storageModel; } else { - if (typeof bearerToken === "string") { + if (typeof bearerToken === 'string') { this._model = await StorageModel.create(bearerToken); } } @@ -52,6 +52,6 @@ export class Machine { } public async say(key: TI18nKey, options?: object) { - this._sayAcc += this._i18n.t(key, options) + "\n"; + this._sayAcc += this._i18n.t(key, options) + '\n'; } } diff --git a/webhooks/functions/src/controller/assistant.ts b/webhooks/functions/src/controller/assistant.ts index f25a7bfe..8da76415 100644 --- a/webhooks/functions/src/controller/assistant.ts +++ b/webhooks/functions/src/controller/assistant.ts @@ -1,23 +1,21 @@ -import { BaseApp, conversation, ConversationV3, ConversationV3App, OmniHandler } from '@assistant/conversation'; +import {BaseApp, conversation, ConversationV3, ConversationV3App, OmniHandler} from '@assistant/conversation'; import {PROJECT_ID} from '../constants'; -import { StorageModel } from '../model/storage.model'; -import { IConversationV3App, THandlerFn, TMachine } from '../type'; -import { TSdkHandler } from '../typings/sdkHandler'; -import { Machine } from './Machine'; +import {StorageModel} from '../model/storage.model'; +import {THandlerFn} from '../type'; +import {TSdkHandler} from '../typings/sdkHandler'; +import {Machine} from './Machine'; export class Assistant { - private _app: OmniHandler & BaseApp & ConversationV3App; private _storageModel: StorageModel | undefined; - + constructor({ - storageModel + storageModel, }: { storageModel?: StorageModel, }) { - this._app = conversation({ - // verification: PROJECT_ID, + verification: process.env['NODE_ENV'] === 'PRODUCTION' ? PROJECT_ID : undefined, debug: true, }); @@ -38,11 +36,10 @@ export class Assistant { public handle = (path: TSdkHandler, fn: THandlerFn) => { this._app.handle(path, async (conv) => { - const machine = new Machine(conv); const bearerToken = conv.user.params.bearerToken; - await machine.begin({ bearerToken, storageModel: this._storageModel }); + await machine.begin({bearerToken, storageModel: this._storageModel}); await Promise.resolve(fn(machine)); diff --git a/webhooks/functions/src/model/storage.test.ts b/webhooks/functions/src/model/storage.test.ts index ce9c1468..c8e45ef8 100644 --- a/webhooks/functions/src/model/storage.test.ts +++ b/webhooks/functions/src/model/storage.test.ts @@ -6,9 +6,9 @@ import {inspect} from 'util'; import * as chai from 'chai'; // import { StorageModel } from './storage.model'; import * as sinon from 'sinon'; -import * as proxyquire from 'proxyquire'; import {StorageModel} from './storage.model'; +import {storageModelMocked} from '../test/utils.test'; chai.should(); @@ -256,19 +256,16 @@ describe('storage Model', () => { }, }; - let data: StorageModel; - const pull = sinon.stub().resolves({}); - const push = sinon.stub(); - beforeEach(async () => { - const {StorageModel: _storageModel} = proxyquire('./storage.model', { - './database': { - pull, - push, - }, - }) as { StorageModel: StorageModel & { create: typeof StorageModel.create } }; + // @ts-ignore + let {data, push, pull}: { + data: StorageModel; + pull: sinon.SinonStub; + push: sinon.SinonStub; + } = {}; - data = await _storageModel.create('test'); + beforeEach(async () => { + ({data, push, pull} = await storageModelMocked()); }); it('create a storeModel', async () => { diff --git a/webhooks/functions/src/sdk/conv.test.ts b/webhooks/functions/src/sdk/conv.test.ts index edeea2f0..28b36b54 100644 --- a/webhooks/functions/src/sdk/conv.test.ts +++ b/webhooks/functions/src/sdk/conv.test.ts @@ -1,209 +1,209 @@ export const headers = { - "host": "fb9b-89-90-221-249.ngrok.io", - "user-agent": "Google-ActionsOnGoogle/1.0", - "content-length": "755", - "accept-encoding": "gzip, deflate, br", - "content-type": "application/json;charset=UTF-8", - "google-actions-api-version": "3", - "google-assistant-signature": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjllYWEwMjZmNjM1MTU3ZGZhZDUzMmU0MTgzYTZiODIzZDc1MmFkMWQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhdWQiOiJlZHJsYWItMSIsIm5iZiI6MTY0MzkwNTY0OSwiaWF0IjoxNjQzOTA1OTQ5LCJleHAiOjE2NDM5MDYwNjksImp0aSI6ImQwMzQ1NmU3NDk5MWUxNGY0NjAwYjZhZWIxMWUzMzdkZDc2ODJkYjIifQ.gJ3hcEEw0qfUGf7z4WBFee4D9kdxV9kQzjbbhmL17K_nSTnrMISJZyj1DlmmcPragmp6EXWbJ14zTIzmrKPoDbEyx8H4PYG3h6vSGo4tlyB_H69hr0QKRU8fCc5lBQXVMGViuJBAMI9jWP28H2nt7hV0p-_AHayJnEvwSju5ojcd9wAalpTYcJagfdTkT2kvJEh_GeyooZvPZEOnx0vc3laTvrQqdxgP6Sh4wHbJnptj4bUiUirONuFp63C9Y92zkQPDD6tiQ8an475EjI9cys_-KDtXBhfx4Ojo3M0_9jBgpN67aDVk0vOnHYtnXzBg_fZhiM0sLaZRbe49LucHHw", - "x-forwarded-for": "66.249.81.244", - "x-forwarded-proto": "https", - "connection": "close" + 'host': 'fb9b-89-90-221-249.ngrok.io', + 'user-agent': 'Google-ActionsOnGoogle/1.0', + 'content-length': '755', + 'accept-encoding': 'gzip, deflate, br', + 'content-type': 'application/json;charset=UTF-8', + 'google-actions-api-version': '3', + 'google-assistant-signature': 'eyJhbGciOiJSUzI1NiIsImtpZCI6IjllYWEwMjZmNjM1MTU3ZGZhZDUzMmU0MTgzYTZiODIzZDc1MmFkMWQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhdWQiOiJlZHJsYWItMSIsIm5iZiI6MTY0MzkwNTY0OSwiaWF0IjoxNjQzOTA1OTQ5LCJleHAiOjE2NDM5MDYwNjksImp0aSI6ImQwMzQ1NmU3NDk5MWUxNGY0NjAwYjZhZWIxMWUzMzdkZDc2ODJkYjIifQ.gJ3hcEEw0qfUGf7z4WBFee4D9kdxV9kQzjbbhmL17K_nSTnrMISJZyj1DlmmcPragmp6EXWbJ14zTIzmrKPoDbEyx8H4PYG3h6vSGo4tlyB_H69hr0QKRU8fCc5lBQXVMGViuJBAMI9jWP28H2nt7hV0p-_AHayJnEvwSju5ojcd9wAalpTYcJagfdTkT2kvJEh_GeyooZvPZEOnx0vc3laTvrQqdxgP6Sh4wHbJnptj4bUiUirONuFp63C9Y92zkQPDD6tiQ8an475EjI9cys_-KDtXBhfx4Ojo3M0_9jBgpN67aDVk0vOnHYtnXzBg_fZhiM0sLaZRbe49LucHHw', + 'x-forwarded-for': '66.249.81.244', + 'x-forwarded-proto': 'https', + 'connection': 'close', }; export const request = { - "handler": { - "name": "main" - }, - "intent": { - "name": "actions.intent.MAIN", - "params": {}, - "query": "Parler avec dev edrlab" - }, - "scene": { - "name": "actions.scene.START_CONVERSATION", - "slotFillingStatus": "UNSPECIFIED", - "slots": {} - }, - "session": { - "id": "ABwppHGoBsXu3JLKx1PW4N40zjedGWXq2Ln6bsc9POLhC2rshmkstBG-u7EAq2UZ7tjBRmoMgGc", - "params": {}, - "typeOverrides": [], - "languageCode": "" - }, - "user": { - "locale": "fr-CA", - "params": { - "bearerToken": "" - }, - "accountLinkingStatus": "ACCOUNT_LINKING_STATUS_UNSPECIFIED", - "verificationStatus": "VERIFIED", - "packageEntitlements": [], - "gaiamint": "", - "permissions": [], - "lastSeenTime": "2022-02-03T16:15:10Z" - }, - "home": { - "params": {} - }, - "device": { - "capabilities": [ - "SPEECH", - "RICH_RESPONSE", - "LONG_FORM_AUDIO" - ], - "timeZone": { - "id": "Europe/Paris", - "version": "" - } - } + 'handler': { + 'name': 'main', + }, + 'intent': { + 'name': 'actions.intent.MAIN', + 'params': {}, + 'query': 'Parler avec dev edrlab', + }, + 'scene': { + 'name': 'actions.scene.START_CONVERSATION', + 'slotFillingStatus': 'UNSPECIFIED', + 'slots': {}, + }, + 'session': { + 'id': 'ABwppHGoBsXu3JLKx1PW4N40zjedGWXq2Ln6bsc9POLhC2rshmkstBG-u7EAq2UZ7tjBRmoMgGc', + 'params': {}, + 'typeOverrides': [], + 'languageCode': '', + }, + 'user': { + 'locale': 'fr-CA', + 'params': { + 'bearerToken': '', + }, + 'accountLinkingStatus': 'ACCOUNT_LINKING_STATUS_UNSPECIFIED', + 'verificationStatus': 'VERIFIED', + 'packageEntitlements': [], + 'gaiamint': '', + 'permissions': [], + 'lastSeenTime': '2022-02-03T16:15:10Z', + }, + 'home': { + 'params': {}, + }, + 'device': { + 'capabilities': [ + 'SPEECH', + 'RICH_RESPONSE', + 'LONG_FORM_AUDIO', + ], + 'timeZone': { + 'id': 'Europe/Paris', + 'version': '', + }, + }, }; export const convRequestInHandle = { - "overwrite": true, - "digested": false, - "request": { - "handler": { - "name": "main" - }, - "intent": { - "name": "actions.intent.MAIN", - "params": {}, - "query": "Parler avec dev edrlab" - }, - "scene": { - "name": "actions.scene.START_CONVERSATION", - "slotFillingStatus": "UNSPECIFIED", - "slots": {} - }, - "session": { - "id": "ABwppHEDTsgFwQdV_QSp5YvBdnevHBjuyCHzGH-6VPE-IOTt9RmVZieVouqECeLyyO4g29pOHPA", - "params": {}, - "typeOverrides": [], - "languageCode": "" - }, - "user": { - "locale": "fr-CA", - "params": { - "bearerToken": "bearer token not defined" - }, - "accountLinkingStatus": "ACCOUNT_LINKING_STATUS_UNSPECIFIED", - "verificationStatus": "VERIFIED", - "packageEntitlements": [], - "gaiamint": "", - "permissions": [], - "lastSeenTime": "2022-02-03T16:03:22Z" - }, - "home": { - "params": {} - }, - "device": { - "capabilities": [ - "SPEECH", - "RICH_RESPONSE", - "LONG_FORM_AUDIO" - ], - "timeZone": { - "id": "Europe/Paris", - "version": "" - } - } - }, - "headers": { - "host": "fb9b-89-90-221-249.ngrok.io", - "user-agent": "Google-ActionsOnGoogle/1.0", - "content-length": "755", - "accept-encoding": "gzip, deflate, br", - "content-type": "application/json;charset=UTF-8", - "google-actions-api-version": "3", - "google-assistant-signature": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjllYWEwMjZmNjM1MTU3ZGZhZDUzMmU0MTgzYTZiODIzZDc1MmFkMWQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhdWQiOiJlZHJsYWItMSIsIm5iZiI6MTY0MzkwMzkwNywiaWF0IjoxNjQzOTA0MjA3LCJleHAiOjE2NDM5MDQzMjcsImp0aSI6ImI2OGJkNDM1YjNmNWM1YWVmZmE3OTIwYjNlY2EwMjU0MTkzYjhiOGMifQ.AMiXPH_4OAjSAD9P1dQ0tHGxgdPp0yiHnPeNlH1h1Lmw2fP4URdKiUz7X8fvgFuhgAkffAo9XPKRPeS5JpCCUmQCvjfE4cej45vyHqCjovEBJxuVFwpbmFcilKAIE2JmGoSlDsbyAJvV0c70HiaOjXtVikPll_mprwveXXU3x6OG4pu0Hqqn9RrsQFIyqQ-p9dU1sVjMvIK-Qhg6KRBKfrirEKIz6dCxVZRdj76jYuPZPsmVeLRfwjt8J0GtFHBlAasJxv02Al8WMw0j6GUeN0GkFnVs_0dupgLV1-v2Zhr5BDiCgjHLbwVWIGsh-_4Jay7kjJ2ouh7ZJNTyfc80kg", - "x-forwarded-for": "66.249.81.235", - "x-forwarded-proto": "https", - "connection": "close" + 'overwrite': true, + 'digested': false, + 'request': { + 'handler': { + 'name': 'main', }, - "handler": { - "name": "main" + 'intent': { + 'name': 'actions.intent.MAIN', + 'params': {}, + 'query': 'Parler avec dev edrlab', }, - "intent": { - "name": "actions.intent.MAIN", - "query": "Parler avec dev edrlab", - "params": {} + 'scene': { + 'name': 'actions.scene.START_CONVERSATION', + 'slotFillingStatus': 'UNSPECIFIED', + 'slots': {}, }, - "scene": { - "name": "actions.scene.START_CONVERSATION", - "slotFillingStatus": "UNSPECIFIED", - "slots": {}, - "next": {} + 'session': { + 'id': 'ABwppHEDTsgFwQdV_QSp5YvBdnevHBjuyCHzGH-6VPE-IOTt9RmVZieVouqECeLyyO4g29pOHPA', + 'params': {}, + 'typeOverrides': [], + 'languageCode': '', }, - "session": { - "id": "ABwppHEDTsgFwQdV_QSp5YvBdnevHBjuyCHzGH-6VPE-IOTt9RmVZieVouqECeLyyO4g29pOHPA", - "params": {}, - "typeOverrides": [], - "languageCode": "" + 'user': { + 'locale': 'fr-CA', + 'params': { + 'bearerToken': 'bearer token not defined', + }, + 'accountLinkingStatus': 'ACCOUNT_LINKING_STATUS_UNSPECIFIED', + 'verificationStatus': 'VERIFIED', + 'packageEntitlements': [], + 'gaiamint': '', + 'permissions': [], + 'lastSeenTime': '2022-02-03T16:03:22Z', }, - "user": { - "locale": "fr-CA", - "params": { - "bearerToken": "bearer token not defined" - }, - "accountLinkingStatus": "ACCOUNT_LINKING_STATUS_UNSPECIFIED", - "verificationStatus": "VERIFIED", - "packageEntitlements": [], - "gaiamint": "", - "permissions": [], - "lastSeenTime": "2022-02-03T16:03:22Z" + 'home': { + 'params': {}, }, - "device": { - "capabilities": [ - "SPEECH", - "RICH_RESPONSE", - "LONG_FORM_AUDIO" - ], - "currentLocation": {}, - "timeZone": { - "id": "Europe/Paris", - "version": "" - } + 'device': { + 'capabilities': [ + 'SPEECH', + 'RICH_RESPONSE', + 'LONG_FORM_AUDIO', + ], + 'timeZone': { + 'id': 'Europe/Paris', + 'version': '', + }, }, - "home": { - "params": {} + }, + 'headers': { + 'host': 'fb9b-89-90-221-249.ngrok.io', + 'user-agent': 'Google-ActionsOnGoogle/1.0', + 'content-length': '755', + 'accept-encoding': 'gzip, deflate, br', + 'content-type': 'application/json;charset=UTF-8', + 'google-actions-api-version': '3', + 'google-assistant-signature': 'eyJhbGciOiJSUzI1NiIsImtpZCI6IjllYWEwMjZmNjM1MTU3ZGZhZDUzMmU0MTgzYTZiODIzZDc1MmFkMWQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhdWQiOiJlZHJsYWItMSIsIm5iZiI6MTY0MzkwMzkwNywiaWF0IjoxNjQzOTA0MjA3LCJleHAiOjE2NDM5MDQzMjcsImp0aSI6ImI2OGJkNDM1YjNmNWM1YWVmZmE3OTIwYjNlY2EwMjU0MTkzYjhiOGMifQ.AMiXPH_4OAjSAD9P1dQ0tHGxgdPp0yiHnPeNlH1h1Lmw2fP4URdKiUz7X8fvgFuhgAkffAo9XPKRPeS5JpCCUmQCvjfE4cej45vyHqCjovEBJxuVFwpbmFcilKAIE2JmGoSlDsbyAJvV0c70HiaOjXtVikPll_mprwveXXU3x6OG4pu0Hqqn9RrsQFIyqQ-p9dU1sVjMvIK-Qhg6KRBKfrirEKIz6dCxVZRdj76jYuPZPsmVeLRfwjt8J0GtFHBlAasJxv02Al8WMw0j6GUeN0GkFnVs_0dupgLV1-v2Zhr5BDiCgjHLbwVWIGsh-_4Jay7kjJ2ouh7ZJNTyfc80kg', + 'x-forwarded-for': '66.249.81.235', + 'x-forwarded-proto': 'https', + 'connection': 'close', + }, + 'handler': { + 'name': 'main', + }, + 'intent': { + 'name': 'actions.intent.MAIN', + 'query': 'Parler avec dev edrlab', + 'params': {}, + }, + 'scene': { + 'name': 'actions.scene.START_CONVERSATION', + 'slotFillingStatus': 'UNSPECIFIED', + 'slots': {}, + 'next': {}, + }, + 'session': { + 'id': 'ABwppHEDTsgFwQdV_QSp5YvBdnevHBjuyCHzGH-6VPE-IOTt9RmVZieVouqECeLyyO4g29pOHPA', + 'params': {}, + 'typeOverrides': [], + 'languageCode': '', + }, + 'user': { + 'locale': 'fr-CA', + 'params': { + 'bearerToken': 'bearer token not defined', }, - "expected": {}, - "context": {}, - "prompt": { - "override": false + 'accountLinkingStatus': 'ACCOUNT_LINKING_STATUS_UNSPECIFIED', + 'verificationStatus': 'VERIFIED', + 'packageEntitlements': [], + 'gaiamint': '', + 'permissions': [], + 'lastSeenTime': '2022-02-03T16:03:22Z', + }, + 'device': { + 'capabilities': [ + 'SPEECH', + 'RICH_RESPONSE', + 'LONG_FORM_AUDIO', + ], + 'currentLocation': {}, + 'timeZone': { + 'id': 'Europe/Paris', + 'version': '', }, - // "_internal": { - // "promptSet": false, - // "orig": { - // "scene": { - // "name": "actions.scene.START_CONVERSATION", - // "slotFillingStatus": "UNSPECIFIED", - // "slots": {}, - // "next": {} - // }, - // "session": { - // "id": "ABwppHEDTsgFwQdV_QSp5YvBdnevHBjuyCHzGH-6VPE-IOTt9RmVZieVouqECeLyyO4g29pOHPA", - // "params": {}, - // "typeOverrides": [], - // "languageCode": "" - // }, - // "user": { - // "locale": "fr-CA", - // "params": { - // "bearerToken": "bearer token not defined" - // }, - // "accountLinkingStatus": "ACCOUNT_LINKING_STATUS_UNSPECIFIED", - // "verificationStatus": "VERIFIED", - // "packageEntitlements": [], - // "gaiamint": "", - // "permissions": [], - // "lastSeenTime": "2022-02-03T16:03:22Z" - // }, - // "home": { - // "params": {} - // } - // } - // } -}; \ No newline at end of file + }, + 'home': { + 'params': {}, + }, + 'expected': {}, + 'context': {}, + 'prompt': { + 'override': false, + }, + // "_internal": { + // "promptSet": false, + // "orig": { + // "scene": { + // "name": "actions.scene.START_CONVERSATION", + // "slotFillingStatus": "UNSPECIFIED", + // "slots": {}, + // "next": {} + // }, + // "session": { + // "id": "ABwppHEDTsgFwQdV_QSp5YvBdnevHBjuyCHzGH-6VPE-IOTt9RmVZieVouqECeLyyO4g29pOHPA", + // "params": {}, + // "typeOverrides": [], + // "languageCode": "" + // }, + // "user": { + // "locale": "fr-CA", + // "params": { + // "bearerToken": "bearer token not defined" + // }, + // "accountLinkingStatus": "ACCOUNT_LINKING_STATUS_UNSPECIFIED", + // "verificationStatus": "VERIFIED", + // "packageEntitlements": [], + // "gaiamint": "", + // "permissions": [], + // "lastSeenTime": "2022-02-03T16:03:22Z" + // }, + // "home": { + // "params": {} + // } + // } + // } +}; diff --git a/webhooks/functions/src/sdk/main.test.ts b/webhooks/functions/src/sdk/main.test.ts index 09b8f2ee..eef2d878 100644 --- a/webhooks/functions/src/sdk/main.test.ts +++ b/webhooks/functions/src/sdk/main.test.ts @@ -1,76 +1,24 @@ -import { defaults, shell } from "./utils.test"; +import {expressMocked, shell} from '../test/utils.test'; import * as chai from 'chai'; -import * as sinon from 'sinon'; -import { headers, request } from "./conv.test"; -import { Assistant } from "../controller/Assistant"; -import * as httpMocks from 'node-mocks-http'; -import { handler } from "../controller/handler"; -import * as proxyquire from 'proxyquire'; -import { StorageModel } from "../model/storage.model"; -import { document } from "firebase-functions/v1/firestore"; -import { JsonObject } from "@assistant/conversation"; +// import * as sinon from 'sinon'; +import {headers, request} from './conv.test'; chai.should(); describe('main handler', () => { - describe('sdk', () => { - it('check main scene', (done) => { - shell('cat custom/global/actions.intent.MAIN.yaml | grep "webhookHandler: main"', (stdout) => { - - stdout.should.to.be.eq(" webhookHandler: main\n"); - + stdout.should.to.be.eq(' webhookHandler: main\n'); }, done); - }); -}); + }); describe('app', () => { - it('main', async () => { + const data = await expressMocked(request, headers); - let storageModel: StorageModel; - const pull = sinon.stub().resolves({}); - const push = sinon.stub(); - - const { StorageModel: _storageModel } = proxyquire('../model/storage.model', { - './database': { - pull, - push, - }, - }) as { StorageModel: StorageModel & { create: typeof StorageModel.create } }; - - storageModel = await _storageModel.create('test'); - - const assistant = new Assistant({ storageModel }); - - handler(assistant); - - const req = httpMocks.createRequest({ - body: request, - headers: headers, - method: "POST", - }); - - const res = httpMocks.createResponse({ - eventEmitter: require('events').EventEmitter - }); - - const promise = new Promise((resolve) => res.on('end', () => { - const data = res._getData(); - data.prompt.firstSimple.speech.should.to.be.eq("Welcome to EDRLAB Library!\nTo fully enjoy your audiobooks and access your personal bookshelf, you will need to link your EDRLAB account.\nWould you like to do so now ?\n") - - resolve(); - })); - - assistant.app(req, res); - - return promise; - + data.prompt.firstSimple.speech.should.to.be.eq('Welcome to EDRLAB Library!\nTo fully enjoy your audiobooks and access your personal bookshelf, you will need to link your EDRLAB account.\nWould you like to do so now ?\n'); }); - }); - -}); \ No newline at end of file +}); diff --git a/webhooks/functions/src/sdk/utils.test.ts b/webhooks/functions/src/sdk/utils.test.ts deleted file mode 100644 index 8e0ca031..00000000 --- a/webhooks/functions/src/sdk/utils.test.ts +++ /dev/null @@ -1,20 +0,0 @@ - -// class-transformer -import 'reflect-metadata'; -import { exec } from "child_process"; -export const SDK_PATH = "../../sdk"; - -export const defaults = { - cwd: process.env.PWD + "/" + SDK_PATH, - env: process.env -}; - -export const shell = (s: string, fn: (s: string) => void, done: (...a: any[]) => any) => { - - exec(s, defaults, (err, stdout) => { - - fn(stdout); - - done(err); - }); -} \ No newline at end of file diff --git a/webhooks/functions/src/test/utils.test.ts b/webhooks/functions/src/test/utils.test.ts new file mode 100644 index 00000000..3014a1a2 --- /dev/null +++ b/webhooks/functions/src/test/utils.test.ts @@ -0,0 +1,77 @@ +import * as sinon from 'sinon'; +import * as proxyquire from 'proxyquire'; +import {StorageModel} from '../model/storage.model'; + +// class-transformer +import 'reflect-metadata'; +import {exec} from 'child_process'; +import {JsonObject} from '@assistant/conversation'; +import {Assistant} from '../controller/Assistant'; +import {handler} from '../controller/handler'; +export const SDK_PATH = '../../sdk'; + +import * as httpMocks from 'node-mocks-http'; +import {info} from 'firebase-functions/logger'; + +export const defaults = { + cwd: process.env.PWD + '/' + SDK_PATH, + env: process.env, +}; + +export const shell = (s: string, fn: (s: string) => void, done: (...a: any[]) => any) => { + exec(s, defaults, (err, stdout) => { + fn(stdout); + + done(err); + }); +}; + +export const storageModelMocked = async () => { + const pull = sinon.stub().resolves({}); + const push = sinon.stub(); + + const {StorageModel: _storageModel} = proxyquire('../model/storage.model', { + './database': { + pull, + push, + }, + }) as { StorageModel: StorageModel & { create: typeof StorageModel.create } }; + + const data = await _storageModel.create('test'); + + return { + // @ts-ignore + data, + pull, + push, + }; +}; + +export const expressMocked = async (body: JsonObject, headers: JsonObject) => { + const {data /* , push, pull*/} = await storageModelMocked(); + + const assistant = new Assistant({storageModel: data}); + + handler(assistant); + + const req = httpMocks.createRequest({ + body, + headers, + method: 'POST', + }); + + const res = httpMocks.createResponse({ + eventEmitter: require('events').EventEmitter, + }); + + const promise = new Promise((resolve) => res.on('end', () => { + const data = res._getData(); + + info('DATA RETURNED TO GOOGLE ASSISTANT: ', data); + resolve(data); + })); + + assistant.app(req, res); + + return promise; +}; diff --git a/webhooks/functions/src/translation/index.ts b/webhooks/functions/src/translation/index.ts index 2b4cb5dd..7e6d8547 100644 --- a/webhooks/functions/src/translation/index.ts +++ b/webhooks/functions/src/translation/index.ts @@ -11,7 +11,7 @@ i18next.init({ }, 'en': { translation: enTranslation, - } + }, }, fallbackLng: DEFAULT_LANGUAGE, }); From 4b48e51c03158362e66eee08e436da5efad79e5d Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 7 Feb 2022 14:13:22 +0100 Subject: [PATCH 093/180] dev: launch node14 script in specific dir --- webhooks/functions/cd.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100755 webhooks/functions/cd.sh diff --git a/webhooks/functions/cd.sh b/webhooks/functions/cd.sh new file mode 100755 index 00000000..6e15b752 --- /dev/null +++ b/webhooks/functions/cd.sh @@ -0,0 +1,11 @@ + +function cd { + # actually change the directory with all args passed to the function + builtin cd "$@" + + case $PWD/ in + /Users/edrlab/Documents/edrlab/projects/lis-mon-livre-project/lis-mon-livre-edrlab/webhooks/functions/*) + node14 + ;; + esac +} From 15c75e15f03908ddf71369f9dc85c451fb7f8322 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 7 Feb 2022 14:30:59 +0100 Subject: [PATCH 094/180] ci: debug bugged actions ci and test node matrix --- .github/workflows/webhooks-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/webhooks-test.yml b/.github/workflows/webhooks-test.yml index 3a9fd450..3517531c 100644 --- a/.github/workflows/webhooks-test.yml +++ b/.github/workflows/webhooks-test.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [14.x] + node-version: [12, 14, 16] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ defaults: run: From 215bc597be7706e8b3cd802b1fc66c20e4ac5216 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 7 Feb 2022 14:36:14 +0100 Subject: [PATCH 095/180] ci: debug node version --- .github/workflows/webhooks-test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/webhooks-test.yml b/.github/workflows/webhooks-test.yml index 3517531c..facb5c1c 100644 --- a/.github/workflows/webhooks-test.yml +++ b/.github/workflows/webhooks-test.yml @@ -27,6 +27,8 @@ jobs: with: node-version: ${{ matrix.node }} + - run: node -v + - run: npm -v - run: npm ci - run: npm test - run: npm run lint From 231eae468473504d754d5fc47e78c26a32521df0 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 7 Feb 2022 14:39:31 +0100 Subject: [PATCH 096/180] ci: debug node version --- .github/workflows/webhooks-test.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/webhooks-test.yml b/.github/workflows/webhooks-test.yml index facb5c1c..c4842930 100644 --- a/.github/workflows/webhooks-test.yml +++ b/.github/workflows/webhooks-test.yml @@ -10,7 +10,6 @@ on: jobs: sdk-test-prod: - name: "webhooks unitary tests" runs-on: ubuntu-latest strategy: matrix: @@ -19,14 +18,12 @@ jobs: defaults: run: working-directory: './webhooks/functions' - + name: Node ${{ matrix.node }} webhooks unitary tests steps: - - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: ${{ matrix.node }} - - run: node -v - run: npm -v - run: npm ci From e9bba36ff4f6ff5d477c90aded27b9f7a6378837 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 7 Feb 2022 14:41:51 +0100 Subject: [PATCH 097/180] ci: debug node version typo --- .github/workflows/webhooks-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/webhooks-test.yml b/.github/workflows/webhooks-test.yml index c4842930..53a9445b 100644 --- a/.github/workflows/webhooks-test.yml +++ b/.github/workflows/webhooks-test.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [12, 14, 16] + node: [12, 14, 16] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ defaults: run: From bb73f0c82692bf11173724485b071c2d033f00e6 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 7 Feb 2022 14:45:17 +0100 Subject: [PATCH 098/180] ci: debug with ls --- .github/workflows/webhooks-test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/webhooks-test.yml b/.github/workflows/webhooks-test.yml index 53a9445b..d720769f 100644 --- a/.github/workflows/webhooks-test.yml +++ b/.github/workflows/webhooks-test.yml @@ -26,6 +26,7 @@ jobs: node-version: ${{ matrix.node }} - run: node -v - run: npm -v + - run: ls -la ** - run: npm ci - run: npm test - run: npm run lint From 989c702d55f25c477aa6a0a326db3f6b2473608a Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 7 Feb 2022 14:48:18 +0100 Subject: [PATCH 099/180] ci: debug with ls --- .github/workflows/webhooks-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/webhooks-test.yml b/.github/workflows/webhooks-test.yml index d720769f..c9e6f17f 100644 --- a/.github/workflows/webhooks-test.yml +++ b/.github/workflows/webhooks-test.yml @@ -26,7 +26,7 @@ jobs: node-version: ${{ matrix.node }} - run: node -v - run: npm -v - - run: ls -la ** + - run: find . -type f - run: npm ci - run: npm test - run: npm run lint From a63e2a1d71e28f6d96573d4e4add8c1b3644e761 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 7 Feb 2022 15:04:37 +0100 Subject: [PATCH 100/180] git: reset cache file controller/assistant.ts and Assistant.ts are the same file I don't understand why : It's like a bug in the inode cache --- .../src/controller/{assistant.ts => assistant.ts.backup} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename webhooks/functions/src/controller/{assistant.ts => assistant.ts.backup} (100%) diff --git a/webhooks/functions/src/controller/assistant.ts b/webhooks/functions/src/controller/assistant.ts.backup similarity index 100% rename from webhooks/functions/src/controller/assistant.ts rename to webhooks/functions/src/controller/assistant.ts.backup From 8d3f1ce7c5322a9d5fbe5a88bd7b3eba32ae4e1d Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 7 Feb 2022 15:05:25 +0100 Subject: [PATCH 101/180] git: follow the previous commit and restore controller/Assistant.ts --- .../src/controller/{assistant.ts.backup => Assistant.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename webhooks/functions/src/controller/{assistant.ts.backup => Assistant.ts} (100%) diff --git a/webhooks/functions/src/controller/assistant.ts.backup b/webhooks/functions/src/controller/Assistant.ts similarity index 100% rename from webhooks/functions/src/controller/assistant.ts.backup rename to webhooks/functions/src/controller/Assistant.ts From 23b6f758fd1a21a4d883619006a4e807eb467539 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 7 Feb 2022 16:17:25 +0100 Subject: [PATCH 102/180] feat: main handler --- sdk/custom/scenes/home_new_user.yaml | 1 + sdk/custom/scenes/home_user.yaml | 1 + webhooks/functions/src/controller/Machine.ts | 14 ++++++++ .../functions/src/controller/handler/main.ts | 22 ++++++++++-- webhooks/functions/src/sdk/conv.test.ts | 2 +- webhooks/functions/src/sdk/main.test.ts | 35 ++++++++++++++++--- webhooks/functions/src/translation/en/en.json | 13 +++++-- webhooks/functions/src/typings/i18n.d.ts | 4 +-- webhooks/functions/src/typings/sdkScene.d.ts | 4 +++ 9 files changed, 83 insertions(+), 13 deletions(-) create mode 100644 sdk/custom/scenes/home_new_user.yaml create mode 100644 sdk/custom/scenes/home_user.yaml create mode 100644 webhooks/functions/src/typings/sdkScene.d.ts diff --git a/sdk/custom/scenes/home_new_user.yaml b/sdk/custom/scenes/home_new_user.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/sdk/custom/scenes/home_new_user.yaml @@ -0,0 +1 @@ +{} diff --git a/sdk/custom/scenes/home_user.yaml b/sdk/custom/scenes/home_user.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/sdk/custom/scenes/home_user.yaml @@ -0,0 +1 @@ +{} diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 2d0664e1..e02cc60d 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -2,6 +2,7 @@ import {ok} from 'assert'; import {StorageModel} from '../model/storage.model'; import {i18n, TI18n, TI18nKey} from '../translation'; import {IConversationV3} from '../type'; +import {TSdkScene} from '../typings/sdkScene'; export class Machine { private _conv: IConversationV3; @@ -54,4 +55,17 @@ export class Machine { public async say(key: TI18nKey, options?: object) { this._sayAcc += this._i18n.t(key, options) + '\n'; } + + public get isLinked() { + return this._conv.user.accountLinkingStatus; + } + + public set nextScene(scene: TSdkScene) { + const obj = this._conv.scene; + + if (!obj.next) { + obj.next = {}; + } + obj.next.name = scene; + } } diff --git a/webhooks/functions/src/controller/handler/main.ts b/webhooks/functions/src/controller/handler/main.ts index 8af39e41..5bc9ec18 100644 --- a/webhooks/functions/src/controller/handler/main.ts +++ b/webhooks/functions/src/controller/handler/main.ts @@ -1,10 +1,26 @@ +import { AccountLinkingStatus } from "@assistant/conversation/dist/api/schema"; import { NAME } from "../../constants"; import { TMachine } from "../../type"; export const main = (machine: TMachine) => { - machine.say("main.welcome.1", { name: NAME}); - machine.say("main.welcome.2", { name: NAME}); - machine.say("main.welcome.3"); + const isLinked = machine.isLinked; + + if (isLinked === AccountLinkingStatus.Linked) { + + machine.say("main.welcome.user.1", { name: NAME}); + machine.say("main.welcome.user.2"); + machine.say("main.welcome.user.3"); + + machine.nextScene = "home_user"; + } else { + + machine.say("main.welcome.newUser.1", { name: NAME}); + machine.say("main.welcome.newUser.2", { name: NAME}); + machine.say("main.welcome.newUser.3"); + + machine.nextScene = "home_new_user"; + } + } \ No newline at end of file diff --git a/webhooks/functions/src/sdk/conv.test.ts b/webhooks/functions/src/sdk/conv.test.ts index 28b36b54..694886cf 100644 --- a/webhooks/functions/src/sdk/conv.test.ts +++ b/webhooks/functions/src/sdk/conv.test.ts @@ -12,7 +12,7 @@ export const headers = { 'connection': 'close', }; -export const request = { +export const body = { 'handler': { 'name': 'main', }, diff --git a/webhooks/functions/src/sdk/main.test.ts b/webhooks/functions/src/sdk/main.test.ts index eef2d878..32c09841 100644 --- a/webhooks/functions/src/sdk/main.test.ts +++ b/webhooks/functions/src/sdk/main.test.ts @@ -1,7 +1,7 @@ import {expressMocked, shell} from '../test/utils.test'; import * as chai from 'chai'; // import * as sinon from 'sinon'; -import {headers, request} from './conv.test'; +import {headers, body} from './conv.test'; chai.should(); @@ -15,10 +15,37 @@ describe('main handler', () => { }); describe('app', () => { - it('main', async () => { - const data = await expressMocked(request, headers); + it('main new user unspecified', async () => { + body.user.accountLinkingStatus = 'ACCOUNT_LINKING_STATUS_UNSPECIFIED'; + const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq('Welcome to EDRLAB Library!\nTo fully enjoy your audiobooks and access your personal bookshelf, you will need to link your EDRLAB account.\nWould you like to do so now ?\n'); + const welcomeNewUser = 'Welcome to EDRLAB Library!\nTo fully enjoy your audiobooks and access your personal bookshelf, you will need to link your EDRLAB account.\nWould you like to do so now ?\n'; + + data.prompt.firstSimple.speech.should.to.be.eq(welcomeNewUser); + + data.scene.next.name.should.to.be.eq('home_new_user'); + }); + + it('main new user not linked', async () => { + body.user.accountLinkingStatus = 'NOT_LINKED'; + const data = await expressMocked(body, headers); + + const welcomeNewUser = 'Welcome to EDRLAB Library!\nTo fully enjoy your audiobooks and access your personal bookshelf, you will need to link your EDRLAB account.\nWould you like to do so now ?\n'; + + data.prompt.firstSimple.speech.should.to.be.eq(welcomeNewUser); + + data.scene.next.name.should.to.be.eq('home_new_user'); + }); + + it('main new user linked', async () => { + body.user.accountLinkingStatus = 'LINKED'; + const data = await expressMocked(body, headers); + + const welcomeUser = 'Welcome back to your EDRLAB Library!\nCongratulations! You have succesfully linked your account and can now access all of your favorite books!\nWould you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection?\n'; + + data.prompt.firstSimple.speech.should.to.be.eq(welcomeUser); + + data.scene.next.name.should.to.be.eq('home_user'); }); }); }); diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index fc514cf1..e242cc2f 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -1,9 +1,16 @@ { "main": { "welcome": { - "1": "Welcome to {{- name}} Library!", - "2": "To fully enjoy your audiobooks and access your personal bookshelf, you will need to link your {{- name}} account.", - "3": "Would you like to do so now ?" + "newUser": { + "1": "Welcome to {{- name}} Library!", + "2": "To fully enjoy your audiobooks and access your personal bookshelf, you will need to link your {{- name}} account.", + "3": "Would you like to do so now ?" + }, + "user": { + "1": "Welcome back to your {{- name}} Library!", + "2": "Congratulations! You have succesfully linked your account and can now access all of your favorite books!", + "3": "Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection?" + } } } } \ No newline at end of file diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index a08bec0d..2a95021f 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.1" | "main.welcome.2" | "main.welcome.3", + "en": "main.welcome.newUser.1" | "main.welcome.newUser.2" | "main.welcome.newUser.3" | "main.welcome.user.1" | "main.welcome.user.2" | "main.welcome.user.3", "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "en": "en:main.welcome.1" | "en:main.welcome.2" | "en:main.welcome.3", + "en": "en:main.welcome.newUser.1" | "en:main.welcome.newUser.2" | "en:main.welcome.newUser.3" | "en:main.welcome.user.1" | "en:main.welcome.user.2" | "en:main.welcome.user.3", "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } diff --git a/webhooks/functions/src/typings/sdkScene.d.ts b/webhooks/functions/src/typings/sdkScene.d.ts new file mode 100644 index 00000000..c29ea5ec --- /dev/null +++ b/webhooks/functions/src/typings/sdkScene.d.ts @@ -0,0 +1,4 @@ +// npm run scene-typed ; + + +export type TSdkScene = 'home_new_user' | 'home_user'; From 23b13a2c4c2de51ef426fa5a012d18ba4a8fa425 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 7 Feb 2022 18:22:45 +0100 Subject: [PATCH 103/180] feat: home_new_user scene --- sdk/custom/intents/help.yaml | 4 + sdk/custom/intents/maybe_later.yaml | 2 + sdk/custom/intents/no.yaml | 3 + sdk/custom/intents/repeat.yaml | 5 + sdk/custom/intents/yes.yaml | 4 + sdk/custom/scenes/home_new_user.yaml | 33 +++- .../scenes/home_new_user_AccountLinking.yaml | 20 +++ .../scenes/home_new_user_maybe_later.yaml | 1 + sdk/custom/scenes/home_new_user_no.yaml | 1 + sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 10 ++ .../functions/src/controller/Assistant.ts | 2 +- .../src/controller/handler/home_new_user.ts | 58 +++++++ .../functions/src/controller/handler/index.ts | 3 + .../functions/src/controller/handler/void.ts | 5 + webhooks/functions/src/sdk/conv.test.ts | 13 +- .../functions/src/sdk/home_new_user.test.ts | 162 ++++++++++++++++++ webhooks/functions/src/sdk/main.test.ts | 2 +- webhooks/functions/src/test/utils.test.ts | 7 +- webhooks/functions/src/translation/en/en.json | 19 +- webhooks/functions/src/typings/i18n.d.ts | 4 +- .../functions/src/typings/sdkHandler.d.ts | 2 +- webhooks/functions/src/typings/sdkScene.d.ts | 2 +- 22 files changed, 350 insertions(+), 12 deletions(-) create mode 100644 sdk/custom/intents/help.yaml create mode 100644 sdk/custom/intents/maybe_later.yaml create mode 100644 sdk/custom/intents/no.yaml create mode 100644 sdk/custom/intents/repeat.yaml create mode 100644 sdk/custom/intents/yes.yaml create mode 100644 sdk/custom/scenes/home_new_user_AccountLinking.yaml create mode 100644 sdk/custom/scenes/home_new_user_maybe_later.yaml create mode 100644 sdk/custom/scenes/home_new_user_no.yaml create mode 100644 webhooks/functions/src/controller/handler/home_new_user.ts create mode 100644 webhooks/functions/src/controller/handler/void.ts create mode 100644 webhooks/functions/src/sdk/home_new_user.test.ts diff --git a/sdk/custom/intents/help.yaml b/sdk/custom/intents/help.yaml new file mode 100644 index 00000000..13c3f3b2 --- /dev/null +++ b/sdk/custom/intents/help.yaml @@ -0,0 +1,4 @@ +trainingPhrases: +- help me please +- help me +- help diff --git a/sdk/custom/intents/maybe_later.yaml b/sdk/custom/intents/maybe_later.yaml new file mode 100644 index 00000000..84b02acc --- /dev/null +++ b/sdk/custom/intents/maybe_later.yaml @@ -0,0 +1,2 @@ +trainingPhrases: +- maybe later diff --git a/sdk/custom/intents/no.yaml b/sdk/custom/intents/no.yaml new file mode 100644 index 00000000..6ac8e817 --- /dev/null +++ b/sdk/custom/intents/no.yaml @@ -0,0 +1,3 @@ +trainingPhrases: +- "n" +- "no" diff --git a/sdk/custom/intents/repeat.yaml b/sdk/custom/intents/repeat.yaml new file mode 100644 index 00000000..0f819691 --- /dev/null +++ b/sdk/custom/intents/repeat.yaml @@ -0,0 +1,5 @@ +trainingPhrases: +- I do not understand +- can you repeat +- repeat please +- repeat diff --git a/sdk/custom/intents/yes.yaml b/sdk/custom/intents/yes.yaml new file mode 100644 index 00000000..60b9c8ab --- /dev/null +++ b/sdk/custom/intents/yes.yaml @@ -0,0 +1,4 @@ +trainingPhrases: +- "y" +- yep +- "yes" diff --git a/sdk/custom/scenes/home_new_user.yaml b/sdk/custom/scenes/home_new_user.yaml index 0967ef42..17efb580 100644 --- a/sdk/custom/scenes/home_new_user.yaml +++ b/sdk/custom/scenes/home_new_user.yaml @@ -1 +1,32 @@ -{} +intentEvents: +- handler: + webhookHandler: home_new_user__intent__help + intent: help +- handler: + webhookHandler: home_new_user__intent__maybe_later + intent: maybe_later +- handler: + webhookHandler: home_new_user__intent__no + intent: "no" +- handler: + webhookHandler: home_new_user__intent__repeat + intent: repeat +- handler: + webhookHandler: home_new_user__intent__yes + intent: "yes" + transitionToScene: home_new_user_AccountLinking +- handler: + webhookHandler: home_new_user__intent__fallback + intent: actions.intent.NO_MATCH_1 +- handler: + webhookHandler: home_new_user__intent__fallback + intent: actions.intent.NO_MATCH_2 +- handler: + webhookHandler: home_new_user__intent__fallback_end + intent: actions.intent.NO_MATCH_FINAL +- handler: + webhookHandler: home_new_user__intent__silence + intent: actions.intent.NO_INPUT_1 +- handler: + webhookHandler: home_new_user__intent__silence_end + intent: actions.intent.NO_INPUT_FINAL diff --git a/sdk/custom/scenes/home_new_user_AccountLinking.yaml b/sdk/custom/scenes/home_new_user_AccountLinking.yaml new file mode 100644 index 00000000..88d96d7b --- /dev/null +++ b/sdk/custom/scenes/home_new_user_AccountLinking.yaml @@ -0,0 +1,20 @@ +conditionalEvents: +- condition: session.params.AccountLinkingSlot == "LINKED" + handler: + webhookHandler: home_new_user_AccountLinking__linked +- condition: session.params.AccountLinkingSlot == "ERROR" + transitionToScene: actions.scene.END_CONVERSATION +- condition: session.params.AccountLinkingSlot == "REJECTED" + transitionToScene: actions.scene.END_CONVERSATION +slots: +- commitBehavior: + writeSessionParam: AccountLinkingSlot + config: + '@type': type.googleapis.com/google.actions.conversation.v3.SignInSpec + opt_context: To keep using EDRLab + defaultValue: + sessionParam: AccountLinkingSlot + name: AccountLinkingSlot + required: true + type: + name: actions.type.AccountLinking diff --git a/sdk/custom/scenes/home_new_user_maybe_later.yaml b/sdk/custom/scenes/home_new_user_maybe_later.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/sdk/custom/scenes/home_new_user_maybe_later.yaml @@ -0,0 +1 @@ +{} diff --git a/sdk/custom/scenes/home_new_user_no.yaml b/sdk/custom/scenes/home_new_user_no.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/sdk/custom/scenes/home_new_user_no.yaml @@ -0,0 +1 @@ +{} diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index 12a5b47c..ff56874f 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -1,6 +1,16 @@ handlers: - name: cancel - name: main +- name: home_new_user__intent__help +- name: home_new_user__intent__maybe_later +- name: home_new_user__intent__no +- name: home_new_user__intent__repeat +- name: home_new_user__intent__yes +- name: home_new_user__intent__fallback +- name: home_new_user__intent__fallback_end +- name: home_new_user__intent__silence +- name: home_new_user__intent__silence_end +- name: home_new_user_AccountLinking__linked httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/controller/Assistant.ts b/webhooks/functions/src/controller/Assistant.ts index 8da76415..3607b5d8 100644 --- a/webhooks/functions/src/controller/Assistant.ts +++ b/webhooks/functions/src/controller/Assistant.ts @@ -16,7 +16,7 @@ export class Assistant { }) { this._app = conversation({ verification: process.env['NODE_ENV'] === 'PRODUCTION' ? PROJECT_ID : undefined, - debug: true, + debug: false, }); this._app.catch((conv, error) => { diff --git a/webhooks/functions/src/controller/handler/home_new_user.ts b/webhooks/functions/src/controller/handler/home_new_user.ts new file mode 100644 index 00000000..cec5b609 --- /dev/null +++ b/webhooks/functions/src/controller/handler/home_new_user.ts @@ -0,0 +1,58 @@ +import { NAME } from "../../constants"; +import { THandlerFn } from "../../type"; +import { Assistant } from "../Assistant"; +import { missing } from "./void"; + +export const home_new_user = (app: Assistant) => { + + app.handle("home_new_user__intent__fallback", help); + app.handle("home_new_user__intent__fallback_end", missing); + app.handle("home_new_user__intent__help", help); + app.handle("home_new_user__intent__maybe_later", maybeLater); + app.handle("home_new_user__intent__no", no); + app.handle("home_new_user__intent__repeat", repeat); + app.handle("home_new_user__intent__silence", help); + app.handle("home_new_user__intent__silence_end", missing); + app.handle("home_new_user__intent__yes", yes); + +} + +const help: THandlerFn = (m) => { + + m.say("home_new_user.help.1", {name: NAME}); + m.say("home_new_user.help.2", {name: NAME}); + + m.nextScene = "home_new_user"; +} + +const maybeLater: THandlerFn = (m) => { + + m.say("home_new_user.maybeLater.1", {name: NAME}); + m.say("home_new_user.maybeLater.2") + + m.nextScene = "home_new_user_maybe_later"; +} + +const yes: THandlerFn = (m) => { + + // do nothing + + +} + +const no: THandlerFn = (m) => { + + m.say("home_new_user.no.1", {name: NAME}); + m.say("home_new_user.no.2", {name: NAME}); + + m.nextScene = "home_new_user_no"; +} + +const repeat: THandlerFn = (m) => { + + m.say("main.welcome.newUser.1", { name: NAME }); + m.say("main.welcome.newUser.2", { name: NAME }); + m.say("main.welcome.newUser.3"); + + m.nextScene = "home_new_user"; +} \ No newline at end of file diff --git a/webhooks/functions/src/controller/handler/index.ts b/webhooks/functions/src/controller/handler/index.ts index d62f3171..cc1a30f7 100644 --- a/webhooks/functions/src/controller/handler/index.ts +++ b/webhooks/functions/src/controller/handler/index.ts @@ -1,7 +1,10 @@ import { Assistant } from "../Assistant"; +import { home_new_user } from "./home_new_user"; import { main } from "./main"; export const handler = (app = new Assistant({})) => { app.handle('main', main); + + home_new_user(app); } \ No newline at end of file diff --git a/webhooks/functions/src/controller/handler/void.ts b/webhooks/functions/src/controller/handler/void.ts new file mode 100644 index 00000000..b9e8c207 --- /dev/null +++ b/webhooks/functions/src/controller/handler/void.ts @@ -0,0 +1,5 @@ +import { THandlerFn } from "../../type"; + +export const missing: THandlerFn = (m) => { + m.say("void"); +} \ No newline at end of file diff --git a/webhooks/functions/src/sdk/conv.test.ts b/webhooks/functions/src/sdk/conv.test.ts index 694886cf..833cea2c 100644 --- a/webhooks/functions/src/sdk/conv.test.ts +++ b/webhooks/functions/src/sdk/conv.test.ts @@ -12,7 +12,16 @@ export const headers = { 'connection': 'close', }; -export const body = { +export let body: ReturnType; + + +// beforeEach save my life ! +// thanks you mocha +beforeEach(() => { + body = bodyCopy(); +}) + +const bodyCopy = () => Object.assign({}, { 'handler': { 'name': 'main', }, @@ -58,7 +67,7 @@ export const body = { 'version': '', }, }, -}; +}); export const convRequestInHandle = { 'overwrite': true, diff --git a/webhooks/functions/src/sdk/home_new_user.test.ts b/webhooks/functions/src/sdk/home_new_user.test.ts new file mode 100644 index 00000000..81d51182 --- /dev/null +++ b/webhooks/functions/src/sdk/home_new_user.test.ts @@ -0,0 +1,162 @@ +import {expressMocked, shell} from '../test/utils.test'; +import * as chai from 'chai'; +// import * as sinon from 'sinon'; +import {headers, body} from './conv.test'; + + +chai.should(); + +const scene = 'home_new_user'; + +const yaml = `intentEvents: +- handler: + webhookHandler: home_new_user__intent__help + intent: help +- handler: + webhookHandler: home_new_user__intent__maybe_later + intent: maybe_later +- handler: + webhookHandler: home_new_user__intent__no + intent: "no" +- handler: + webhookHandler: home_new_user__intent__repeat + intent: repeat +- handler: + webhookHandler: home_new_user__intent__yes + intent: "yes" + transitionToScene: home_new_user_AccountLinking +- handler: + webhookHandler: home_new_user__intent__fallback + intent: actions.intent.NO_MATCH_1 +- handler: + webhookHandler: home_new_user__intent__fallback + intent: actions.intent.NO_MATCH_2 +- handler: + webhookHandler: home_new_user__intent__fallback_end + intent: actions.intent.NO_MATCH_FINAL +- handler: + webhookHandler: home_new_user__intent__silence + intent: actions.intent.NO_INPUT_1 +- handler: + webhookHandler: home_new_user__intent__silence_end + intent: actions.intent.NO_INPUT_FINAL +`; + +describe('home_new_user handler', () => { + describe('sdk', () => { + it('check main scene', (done) => { + shell(`cat custom/scenes/${scene}.yaml`, (stdout) => { + stdout.should.to.be.eq(yaml); + }, done); + }); + }); + + describe('app', () => { + it('yes', async () => { + body.handler.name = 'home_new_user__intent__yes'; + body.scene.name = scene; + + await expressMocked(body, headers); + + // expect authentication + // automatic transition to account linking + }); + + it('no', async () => { + body.handler.name = 'home_new_user__intent__no'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + console.log(data.prompt.firstSimple); + + const message = `In order to read books using the EDRLAB Library via Google, you need to be a registered EDRLAB member and link your account.\nWould you like to learn more about EDRLAB?\n`; + data.prompt.firstSimple.speech.should.to.be.eq(message); + + data.scene.next.name.should.to.be.eq('home_new_user_no'); + }); + + it('repeat', async () => { + body.handler.name = 'home_new_user__intent__repeat'; + body.scene.name = scene; + + const message = `Welcome to EDRLAB Library!\nTo fully enjoy your audiobooks and access your personal bookshelf, you will need to link your EDRLAB account.\nWould you like to do so now ?\n`; + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + + data.scene.next.name.should.to.be.eq('home_new_user'); + }); + + it('maybeLater', async () => { + body.handler.name = 'home_new_user__intent__maybe_later'; + body.scene.name = scene; + + const message = `Of course! you can learn more about EDRLAB or quit for now.\nWhat would you like to do?\n`; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + + data.scene.next.name.should.to.be.eq('home_new_user_maybe_later'); + }); + + const help = `To fully experience EDRLAB Library, and enjoy your favorite audiobooks via Google, you'll need to connect your CELA account. To do so, answer 'yes' when prompted and follow the instructions. I will then send a connection link, that you will find into the Google Home application. You will have to log in to your CELA account. You'll only have to do this once, and you'll be all set to start enjoying the wonderful world of EDRLAB books for hours on end!\nWould you like to link your account right now?\n`; + + it('help', async () => { + body.handler.name = 'home_new_user__intent__help'; + body.scene.name = scene; + + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('home_new_user'); + }); + + it('fallback 1 and 2', async () => { + body.handler.name = 'home_new_user__intent__help'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('home_new_user'); + }); + + it('fallback 3', async () => { + body.handler.name = 'home_new_user__intent__fallback_end'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + + // data.scene.next.name.should.to.be.eq('home_new_user'); + }); + + it('silence 1 and 2', async () => { + body.handler.name = 'home_new_user__intent__silence'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('home_new_user'); + }); + + it('silence 3', async () => { + body.handler.name = 'home_new_user__intent__fallback_end'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + + // data.scene.next.name.should.to.be.eq('home_new_user'); + }); + }); +}); diff --git a/webhooks/functions/src/sdk/main.test.ts b/webhooks/functions/src/sdk/main.test.ts index 32c09841..9c05d56c 100644 --- a/webhooks/functions/src/sdk/main.test.ts +++ b/webhooks/functions/src/sdk/main.test.ts @@ -41,7 +41,7 @@ describe('main handler', () => { body.user.accountLinkingStatus = 'LINKED'; const data = await expressMocked(body, headers); - const welcomeUser = 'Welcome back to your EDRLAB Library!\nCongratulations! You have succesfully linked your account and can now access all of your favorite books!\nWould you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection?\n'; + const welcomeUser = 'Welcome back to your EDRLAB Library!\nCongratulations! You have succesfully linked your account and can now access all of your favorite books!\nWould you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection?\n'; data.prompt.firstSimple.speech.should.to.be.eq(welcomeUser); diff --git a/webhooks/functions/src/test/utils.test.ts b/webhooks/functions/src/test/utils.test.ts index 3014a1a2..0e09f70f 100644 --- a/webhooks/functions/src/test/utils.test.ts +++ b/webhooks/functions/src/test/utils.test.ts @@ -64,10 +64,15 @@ export const expressMocked = async (body: JsonObject, headers: JsonObject) => { eventEmitter: require('events').EventEmitter, }); - const promise = new Promise((resolve) => res.on('end', () => { + const promise = new Promise((resolve, reject) => res.on('end', () => { const data = res._getData(); info('DATA RETURNED TO GOOGLE ASSISTANT: ', data); + + if (data.error) { + reject(data.error); + } + resolve(data); })); diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index e242cc2f..bcf6bf6f 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -9,8 +9,23 @@ "user": { "1": "Welcome back to your {{- name}} Library!", "2": "Congratulations! You have succesfully linked your account and can now access all of your favorite books!", - "3": "Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection?" + "3": "Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection?" } } - } + }, + "home_new_user": { + "no": { + "1": "In order to read books using the {{- name}} Library via Google, you need to be a registered {{- name}} member and link your account.", + "2": "Would you like to learn more about {{- name}}?" + }, + "help": { + "1": "To fully experience {{- name}} Library, and enjoy your favorite audiobooks via Google, you'll need to connect your CELA account. To do so, answer 'yes' when prompted and follow the instructions. I will then send a connection link, that you will find into the Google Home application. You will have to log in to your CELA account. You'll only have to do this once, and you'll be all set to start enjoying the wonderful world of {{- name}} books for hours on end!", + "2": "Would you like to link your account right now?" + }, + "maybeLater": { + "1": "Of course! you can learn more about {{- name}} or quit for now.", + "2": "What would you like to do?" + } + }, + "void": "need to replace this message" } \ No newline at end of file diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index 2a95021f..edc7d494 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.newUser.1" | "main.welcome.newUser.2" | "main.welcome.newUser.3" | "main.welcome.user.1" | "main.welcome.user.2" | "main.welcome.user.3", + "en": "main.welcome.newUser.1" | "main.welcome.newUser.2" | "main.welcome.newUser.3" | "main.welcome.user.1" | "main.welcome.user.2" | "main.welcome.user.3" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "void", "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "en": "en:main.welcome.newUser.1" | "en:main.welcome.newUser.2" | "en:main.welcome.newUser.3" | "en:main.welcome.user.1" | "en:main.welcome.user.2" | "en:main.welcome.user.3", + "en": "en:main.welcome.newUser.1" | "en:main.welcome.newUser.2" | "en:main.welcome.newUser.3" | "en:main.welcome.user.1" | "en:main.welcome.user.2" | "en:main.welcome.user.3" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:void", "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index 69f02ae3..a37ae677 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'cancel' | 'media_status' | 'player' | 'ask_to_resume_listening_at_last_offset' | 'main' | 'home_lvl1' | 'home_lvl1__intent__enter_member_space_lvl1' | 'home_lvl1__intent__resume_listening_player' | 'home_lvl1__intent__get_info_association_lvl1' | 'home_lvl1__intent__listen_audiobook_lvl1' | 'home_members_lvl2' | 'home_members_lvl2__intent__listen_audiobook_lvl2' | 'home_members_lvl2__intent__resume_audiobook_lvl2' | 'home_members__intent__selection_audiobook_lvl2' | 'selection_lvl3' | 'selection_lvl3__intent__selection_thematic_list_lvl3' | 'selection_lvl3__intent__selection_genre_lvl3' | 'selection_lvl3__intent__selection_my_list_lvl3' | 'ask_to_resume_listening_at_last_offset__intent__yes' | 'player__intent__resume_listening_player' | 'player__intent__remaining_time_player' | 'search' | 'search__slot__query' | 'search__intent__resume_listening_player' | 'test_player_sdk' | 'test_setup_sdk' | 'test_webhook' | 'ask_to_resume_listening_at_last_offset__intent__no' | 'player__intent__menu' | 'select_publication__slot__number' | 'select_publication__intent__resume_listening_player' | 'select_publication' | 'select_publication__intent__stop' | 'select_publication__intent__next' | 'select_group' | 'select_group__slot__number' | 'select_group__intent__stop' | 'selection_lvl3__intent__selection_all_publication_lvl3' | 'select_publication__intent__repeat' | 'select_group__intent__menu' | 'player_toc' | 'player_toc__intent__repeat' | 'player_toc__intent__next' | 'player_toc__intent__resume_listening_player' | 'player_toc__slot__number' | 'player__intent__listen_toc'; +export type TSdkHandler = 'cancel' | 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked'; diff --git a/webhooks/functions/src/typings/sdkScene.d.ts b/webhooks/functions/src/typings/sdkScene.d.ts index c29ea5ec..da10efee 100644 --- a/webhooks/functions/src/typings/sdkScene.d.ts +++ b/webhooks/functions/src/typings/sdkScene.d.ts @@ -1,4 +1,4 @@ // npm run scene-typed ; -export type TSdkScene = 'home_new_user' | 'home_user'; +export type TSdkScene = 'home_new_user' | 'home_new_user_AccountLinking' | 'home_new_user_maybe_later' | 'home_new_user_no' | 'home_user'; From c52de344848cd1c0eabbe090cc34946f8586916a Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 7 Feb 2022 18:24:33 +0100 Subject: [PATCH 104/180] chore: lint: --- webhooks/functions/src/sdk/conv.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webhooks/functions/src/sdk/conv.test.ts b/webhooks/functions/src/sdk/conv.test.ts index 833cea2c..d602686e 100644 --- a/webhooks/functions/src/sdk/conv.test.ts +++ b/webhooks/functions/src/sdk/conv.test.ts @@ -19,7 +19,7 @@ export let body: ReturnType; // thanks you mocha beforeEach(() => { body = bodyCopy(); -}) +}); const bodyCopy = () => Object.assign({}, { 'handler': { From a629fa39ab3b7ba6cf256af4dc0dccc1cc02e6b0 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 8 Feb 2022 02:18:09 +0100 Subject: [PATCH 105/180] feat home_new_user_maybe_later scene --- sdk/custom/intents/learn_more.yaml | 2 + sdk/custom/intents/link_account.yaml | 3 + sdk/custom/scenes/home_new_user_info.yaml | 1 + .../scenes/home_new_user_maybe_later.yaml | 32 +++- sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 8 + .../handler/home_new_user_maybe_later.ts | 45 ++++++ .../functions/src/controller/handler/index.ts | 2 + .../src/sdk/home_new_user_maybe_later.test.ts | 145 ++++++++++++++++++ webhooks/functions/src/translation/en/en.json | 5 + webhooks/functions/src/typings/i18n.d.ts | 4 +- .../functions/src/typings/sdkHandler.d.ts | 2 +- webhooks/functions/src/typings/sdkScene.d.ts | 2 +- 12 files changed, 246 insertions(+), 5 deletions(-) create mode 100644 sdk/custom/intents/learn_more.yaml create mode 100644 sdk/custom/intents/link_account.yaml create mode 100644 sdk/custom/scenes/home_new_user_info.yaml create mode 100644 webhooks/functions/src/controller/handler/home_new_user_maybe_later.ts create mode 100644 webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts diff --git a/sdk/custom/intents/learn_more.yaml b/sdk/custom/intents/learn_more.yaml new file mode 100644 index 00000000..a98a3043 --- /dev/null +++ b/sdk/custom/intents/learn_more.yaml @@ -0,0 +1,2 @@ +trainingPhrases: +- learn more diff --git a/sdk/custom/intents/link_account.yaml b/sdk/custom/intents/link_account.yaml new file mode 100644 index 00000000..708fe98f --- /dev/null +++ b/sdk/custom/intents/link_account.yaml @@ -0,0 +1,3 @@ +trainingPhrases: +- i want to link my account +- link account diff --git a/sdk/custom/scenes/home_new_user_info.yaml b/sdk/custom/scenes/home_new_user_info.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/sdk/custom/scenes/home_new_user_info.yaml @@ -0,0 +1 @@ +{} diff --git a/sdk/custom/scenes/home_new_user_maybe_later.yaml b/sdk/custom/scenes/home_new_user_maybe_later.yaml index 0967ef42..60954de9 100644 --- a/sdk/custom/scenes/home_new_user_maybe_later.yaml +++ b/sdk/custom/scenes/home_new_user_maybe_later.yaml @@ -1 +1,31 @@ -{} +intentEvents: +- handler: + webhookHandler: home_new_user_maybe_later__intent__learn_more + intent: learn_more +- handler: + webhookHandler: home_new_user_maybe_later__intent__repeat + intent: repeat +- handler: + webhookHandler: home_new_user_maybe_later__intent__link_account + intent: link_account +- handler: + webhookHandler: home_new_user_maybe_later__intent__help + intent: help +- handler: + webhookHandler: home_new_user_maybe_later__intent__fallback + intent: actions.intent.NO_MATCH_1 +- handler: + webhookHandler: home_new_user_maybe_later__intent__fallback + intent: actions.intent.NO_MATCH_2 +- handler: + webhookHandler: home_new_user_maybe_later__intent__fallback_end + intent: actions.intent.NO_MATCH_FINAL +- handler: + webhookHandler: home_new_user_maybe_later__intent__silence + intent: actions.intent.NO_INPUT_1 +- handler: + webhookHandler: home_new_user_maybe_later__intent__silence + intent: actions.intent.NO_INPUT_2 +- handler: + webhookHandler: home_new_user_maybe_later__intent__silence_end + intent: actions.intent.NO_INPUT_FINAL diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index ff56874f..b4a3cdba 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -11,6 +11,14 @@ handlers: - name: home_new_user__intent__silence - name: home_new_user__intent__silence_end - name: home_new_user_AccountLinking__linked +- name: home_new_user_maybe_later__intent__learn_more +- name: home_new_user_maybe_later__intent__repeat +- name: home_new_user_maybe_later__intent__link_account +- name: home_new_user_maybe_later__intent__help +- name: home_new_user_maybe_later__intent__fallback +- name: home_new_user_maybe_later__intent__fallback_end +- name: home_new_user_maybe_later__intent__silence +- name: home_new_user_maybe_later__intent__silence_end httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/controller/handler/home_new_user_maybe_later.ts b/webhooks/functions/src/controller/handler/home_new_user_maybe_later.ts new file mode 100644 index 00000000..f840c613 --- /dev/null +++ b/webhooks/functions/src/controller/handler/home_new_user_maybe_later.ts @@ -0,0 +1,45 @@ +import { NAME } from "../../constants"; +import { THandlerFn } from "../../type"; +import { Assistant } from "../Assistant"; +import { missing } from "./void"; + +export const home_new_user_maybe_later = (app: Assistant) => { + + app.handle("home_new_user_maybe_later__intent__fallback", help); + app.handle("home_new_user_maybe_later__intent__fallback_end", missing); + app.handle("home_new_user_maybe_later__intent__help", help); + app.handle("home_new_user_maybe_later__intent__repeat", repeat); + app.handle("home_new_user_maybe_later__intent__silence", help); + app.handle("home_new_user_maybe_later__intent__silence_end", missing); + app.handle("home_new_user_maybe_later__intent__link_account", linkAccount); + app.handle("home_new_user_maybe_later__intent__learn_more", learnMore); + +} + +const linkAccount: THandlerFn = (m) => { + + m.nextScene = "home_new_user_AccountLinking"; +} + +const help: THandlerFn = (m) => { + + m.say("home_new_user_maybe_later.help.1", {name: NAME}); + + m.nextScene = "home_new_user_maybe_later"; +} + +const repeat: THandlerFn = (m) => { + + m.say("home_new_user.maybeLater.1", { name: NAME }); + m.say("home_new_user.maybeLater.2", { name: NAME }); + + m.nextScene = "home_new_user_maybe_later"; +} + +const learnMore: THandlerFn = (m) => { + + m.say("home_new_user.no.1", { name: NAME }); + m.say("home_new_user.no.2", { name: NAME }); + + m.nextScene = "home_new_user_info"; +} \ No newline at end of file diff --git a/webhooks/functions/src/controller/handler/index.ts b/webhooks/functions/src/controller/handler/index.ts index cc1a30f7..ad6a19dd 100644 --- a/webhooks/functions/src/controller/handler/index.ts +++ b/webhooks/functions/src/controller/handler/index.ts @@ -1,5 +1,6 @@ import { Assistant } from "../Assistant"; import { home_new_user } from "./home_new_user"; +import { home_new_user_maybe_later } from "./home_new_user_maybe_later"; import { main } from "./main"; export const handler = (app = new Assistant({})) => { @@ -7,4 +8,5 @@ export const handler = (app = new Assistant({})) => { app.handle('main', main); home_new_user(app); + home_new_user_maybe_later(app); } \ No newline at end of file diff --git a/webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts b/webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts new file mode 100644 index 00000000..f22873c2 --- /dev/null +++ b/webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts @@ -0,0 +1,145 @@ +import {expressMocked, shell} from '../test/utils.test'; +import * as chai from 'chai'; +// import * as sinon from 'sinon'; +import {headers, body} from './conv.test'; + + +chai.should(); + +const scene = 'home_new_user_maybe_later'; + +const yaml = `intentEvents: +- handler: + webhookHandler: home_new_user_maybe_later__intent__learn_more + intent: learn_more +- handler: + webhookHandler: home_new_user_maybe_later__intent__repeat + intent: repeat +- handler: + webhookHandler: home_new_user_maybe_later__intent__link_account + intent: link_account +- handler: + webhookHandler: home_new_user_maybe_later__intent__help + intent: help +- handler: + webhookHandler: home_new_user_maybe_later__intent__fallback + intent: actions.intent.NO_MATCH_1 +- handler: + webhookHandler: home_new_user_maybe_later__intent__fallback + intent: actions.intent.NO_MATCH_2 +- handler: + webhookHandler: home_new_user_maybe_later__intent__fallback_end + intent: actions.intent.NO_MATCH_FINAL +- handler: + webhookHandler: home_new_user_maybe_later__intent__silence + intent: actions.intent.NO_INPUT_1 +- handler: + webhookHandler: home_new_user_maybe_later__intent__silence + intent: actions.intent.NO_INPUT_2 +- handler: + webhookHandler: home_new_user_maybe_later__intent__silence_end + intent: actions.intent.NO_INPUT_FINAL +`; + +describe('home_new_user_maybe_later handler', () => { + describe('sdk', () => { + it('check main scene', (done) => { + shell(`cat custom/scenes/${scene}.yaml`, (stdout) => { + stdout.should.to.be.eq(yaml); + }, done); + }); + }); + + describe('app', () => { + it('link account', async () => { + body.handler.name = 'home_new_user_maybe_later__intent__link_account'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.scene.next.name.should.to.be.eq('home_new_user_AccountLinking'); + }); + it('no', async () => { + body.handler.name = 'home_new_user_maybe_later__intent__learn_more'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + const message = `In order to read books using the EDRLAB Library via Google, you need to be a registered EDRLAB member and link your account.\nWould you like to learn more about EDRLAB?\n`; + data.prompt.firstSimple.speech.should.to.be.eq(message); + + data.scene.next.name.should.to.be.eq('home_new_user_info'); + }); + + it('repeat', async () => { + body.handler.name = 'home_new_user_maybe_later__intent__repeat'; + body.scene.name = scene; + + const message = `Of course! you can learn more about EDRLAB or quit for now.\nWhat would you like to do?\n`; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + + data.scene.next.name.should.to.be.eq('home_new_user_maybe_later'); + }); + + const help = `You can ask me to link your account, or to learn more about EDRLAB. You can also exit this skill, by simply saying 'stop'. What would you like to do?\n`; + + it('help', async () => { + body.handler.name = 'home_new_user_maybe_later__intent__help'; + body.scene.name = scene; + + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('home_new_user_maybe_later'); + }); + + it('fallback 1 and 2', async () => { + body.handler.name = 'home_new_user_maybe_later__intent__help'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('home_new_user_maybe_later'); + }); + + it('fallback 3', async () => { + body.handler.name = 'home_new_user_maybe_later__intent__fallback_end'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + + // data.scene.next.name.should.to.be.eq('home_new_user'); + }); + + it('silence 1 and 2', async () => { + body.handler.name = 'home_new_user_maybe_later__intent__silence'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('home_new_user_maybe_later'); + }); + + it('silence 3', async () => { + body.handler.name = 'home_new_user_maybe_later__intent__fallback_end'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + + // data.scene.next.name.should.to.be.eq('home_new_user'); + }); + }); +}); diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index bcf6bf6f..a77eaf96 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -27,5 +27,10 @@ "2": "What would you like to do?" } }, + "home_new_user_maybe_later": { + "help": { + "1": "You can ask me to link your account, or to learn more about {{- name}}. You can also exit this skill, by simply saying 'stop'. What would you like to do?" + } + }, "void": "need to replace this message" } \ No newline at end of file diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index edc7d494..b5d1bb8f 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.newUser.1" | "main.welcome.newUser.2" | "main.welcome.newUser.3" | "main.welcome.user.1" | "main.welcome.user.2" | "main.welcome.user.3" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "void", + "en": "main.welcome.newUser.1" | "main.welcome.newUser.2" | "main.welcome.newUser.3" | "main.welcome.user.1" | "main.welcome.user.2" | "main.welcome.user.3" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "void", "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "en": "en:main.welcome.newUser.1" | "en:main.welcome.newUser.2" | "en:main.welcome.newUser.3" | "en:main.welcome.user.1" | "en:main.welcome.user.2" | "en:main.welcome.user.3" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:void", + "en": "en:main.welcome.newUser.1" | "en:main.welcome.newUser.2" | "en:main.welcome.newUser.3" | "en:main.welcome.user.1" | "en:main.welcome.user.2" | "en:main.welcome.user.3" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:void", "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index a37ae677..4d465a9d 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'cancel' | 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked'; +export type TSdkHandler = 'cancel' | 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end'; diff --git a/webhooks/functions/src/typings/sdkScene.d.ts b/webhooks/functions/src/typings/sdkScene.d.ts index da10efee..9cc4677e 100644 --- a/webhooks/functions/src/typings/sdkScene.d.ts +++ b/webhooks/functions/src/typings/sdkScene.d.ts @@ -1,4 +1,4 @@ // npm run scene-typed ; -export type TSdkScene = 'home_new_user' | 'home_new_user_AccountLinking' | 'home_new_user_maybe_later' | 'home_new_user_no' | 'home_user'; +export type TSdkScene = 'home_new_user' | 'home_new_user_AccountLinking' | 'home_new_user_info' | 'home_new_user_maybe_later' | 'home_new_user_no' | 'home_user'; From 11c0d852f7301d21ad86e81573f264ca807b2843 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 8 Feb 2022 14:50:12 +0100 Subject: [PATCH 106/180] feat: info scene --- sdk/custom/intents/membership.yaml | 2 + sdk/custom/scenes/home_new_user_info.yaml | 1 - sdk/custom/scenes/info.yaml | 33 +++++ sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 7 + webhooks/functions/package.json | 3 +- .../handler/home_new_user_maybe_later.ts | 5 +- .../functions/src/controller/handler/index.ts | 2 + .../functions/src/controller/handler/info.ts | 39 +++++ .../functions/src/sdk/home_new_user.test.ts | 2 +- .../src/sdk/home_new_user_maybe_later.test.ts | 7 +- webhooks/functions/src/sdk/info.test.ts | 139 ++++++++++++++++++ webhooks/functions/src/translation/en/en.json | 13 +- webhooks/functions/src/type.ts | 5 +- webhooks/functions/src/typings/i18n.d.ts | 4 +- .../functions/src/typings/sdkHandler.d.ts | 2 +- webhooks/functions/src/typings/sdkScene.d.ts | 2 +- 16 files changed, 251 insertions(+), 15 deletions(-) create mode 100644 sdk/custom/intents/membership.yaml delete mode 100644 sdk/custom/scenes/home_new_user_info.yaml create mode 100644 sdk/custom/scenes/info.yaml create mode 100644 webhooks/functions/src/controller/handler/info.ts create mode 100644 webhooks/functions/src/sdk/info.test.ts diff --git a/sdk/custom/intents/membership.yaml b/sdk/custom/intents/membership.yaml new file mode 100644 index 00000000..c34b6b1d --- /dev/null +++ b/sdk/custom/intents/membership.yaml @@ -0,0 +1,2 @@ +trainingPhrases: +- membership diff --git a/sdk/custom/scenes/home_new_user_info.yaml b/sdk/custom/scenes/home_new_user_info.yaml deleted file mode 100644 index 0967ef42..00000000 --- a/sdk/custom/scenes/home_new_user_info.yaml +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/sdk/custom/scenes/info.yaml b/sdk/custom/scenes/info.yaml new file mode 100644 index 00000000..1d633a20 --- /dev/null +++ b/sdk/custom/scenes/info.yaml @@ -0,0 +1,33 @@ +intentEvents: +- handler: + webhookHandler: info__intent__yes + intent: "yes" + transitionToScene: actions.scene.END_CONVERSATION +- handler: + webhookHandler: info__intent__help + intent: help +- handler: + webhookHandler: info__intent__repeat + intent: repeat +- handler: + webhookHandler: info__intent__yes + intent: membership + transitionToScene: actions.scene.END_CONVERSATION +- handler: + webhookHandler: info__intent__fallback + intent: actions.intent.NO_MATCH_1 +- handler: + webhookHandler: info__intent__fallback + intent: actions.intent.NO_MATCH_2 +- handler: + webhookHandler: info__intent__fallback_end + intent: actions.intent.NO_MATCH_FINAL +- handler: + webhookHandler: info__intent__silence + intent: actions.intent.NO_INPUT_1 +- handler: + webhookHandler: info__intent__silence + intent: actions.intent.NO_INPUT_2 +- handler: + webhookHandler: info__intent__silence_end + intent: actions.intent.NO_INPUT_FINAL diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index b4a3cdba..9837a335 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -19,6 +19,13 @@ handlers: - name: home_new_user_maybe_later__intent__fallback_end - name: home_new_user_maybe_later__intent__silence - name: home_new_user_maybe_later__intent__silence_end +- name: info__intent__yes +- name: info__intent__help +- name: info__intent__repeat +- name: info__intent__fallback +- name: info__intent__fallback_end +- name: info__intent__silence +- name: info__intent__silence_end httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index 05fa57d1..0689500e 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -14,7 +14,8 @@ "lint:fix": "eslint src/**/*.ts --fix", "scene-typed": "echo \"// npm run scene-typed \n\n\nexport type TSdkScene = \"$(for I in `ls ../../sdk/custom/scenes | cut -d \".\" -f1`; do echo \"'$I' |\"; done) | sed 's/..$/;/' > src/typings/sdkScene.d.ts", "handler-typed": "echo \"// npm run handler-typed \n\n\nexport type TSdkHandler = \"$(for I in `cat ../../sdk/webhooks/ActionsOnGoogleFulfillment.yaml | grep \"name:\" | cut -d' ' -s -f3`; do echo \"'$I' |\"; done) | sed 's/..$/;/' > src/typings/sdkHandler.d.ts", - "i18n-typed": "typed-i18next -i src/translation -o src/typings/i18n.d.ts" + "i18n-typed": "typed-i18next -i src/translation -o src/typings/i18n.d.ts", + "typed": "npm run i18n-typed && npm run handler-typed && npm run scene-typed" }, "engines": { "node": "14" diff --git a/webhooks/functions/src/controller/handler/home_new_user_maybe_later.ts b/webhooks/functions/src/controller/handler/home_new_user_maybe_later.ts index f840c613..c091ba52 100644 --- a/webhooks/functions/src/controller/handler/home_new_user_maybe_later.ts +++ b/webhooks/functions/src/controller/handler/home_new_user_maybe_later.ts @@ -38,8 +38,7 @@ const repeat: THandlerFn = (m) => { const learnMore: THandlerFn = (m) => { - m.say("home_new_user.no.1", { name: NAME }); - m.say("home_new_user.no.2", { name: NAME }); + m.say("info.about.1", { name: NAME }); - m.nextScene = "home_new_user_info"; + m.nextScene = "info"; } \ No newline at end of file diff --git a/webhooks/functions/src/controller/handler/index.ts b/webhooks/functions/src/controller/handler/index.ts index ad6a19dd..b1f058b8 100644 --- a/webhooks/functions/src/controller/handler/index.ts +++ b/webhooks/functions/src/controller/handler/index.ts @@ -1,6 +1,7 @@ import { Assistant } from "../Assistant"; import { home_new_user } from "./home_new_user"; import { home_new_user_maybe_later } from "./home_new_user_maybe_later"; +import { info } from "./info"; import { main } from "./main"; export const handler = (app = new Assistant({})) => { @@ -9,4 +10,5 @@ export const handler = (app = new Assistant({})) => { home_new_user(app); home_new_user_maybe_later(app); + info(app); } \ No newline at end of file diff --git a/webhooks/functions/src/controller/handler/info.ts b/webhooks/functions/src/controller/handler/info.ts new file mode 100644 index 00000000..220fee33 --- /dev/null +++ b/webhooks/functions/src/controller/handler/info.ts @@ -0,0 +1,39 @@ +import { NAME } from "../../constants"; +import { THandlerFn } from "../../type"; +import { Assistant } from "../Assistant"; +import { missing } from "./void"; + +export const info = (app: Assistant) => { + + + app.handle("info__intent__yes", membership); + app.handle("info__intent__fallback", help); + app.handle("info__intent__fallback_end", missing); + app.handle("info__intent__help", help); + app.handle("info__intent__repeat", repeat); + app.handle("info__intent__silence", help); + app.handle("info__intent__silence_end", missing); + +} + +const membership: THandlerFn = (m) => { + + m.say('info.yesOrMembership.1', {name: NAME}); + + // @ts-ignore + m.nextScene = "actions.scene.END_CONVERSATION"; +}; + +const help: THandlerFn = (m) => { + + m.say('info.help.1', {name: NAME}); + + m.nextScene = "info"; +} + +const repeat: THandlerFn = (m) => { + + m.say('info.about.1', {name: NAME}); + + m.nextScene = 'info'; +}; diff --git a/webhooks/functions/src/sdk/home_new_user.test.ts b/webhooks/functions/src/sdk/home_new_user.test.ts index 81d51182..4b26287b 100644 --- a/webhooks/functions/src/sdk/home_new_user.test.ts +++ b/webhooks/functions/src/sdk/home_new_user.test.ts @@ -101,7 +101,7 @@ describe('home_new_user handler', () => { data.scene.next.name.should.to.be.eq('home_new_user_maybe_later'); }); - const help = `To fully experience EDRLAB Library, and enjoy your favorite audiobooks via Google, you'll need to connect your CELA account. To do so, answer 'yes' when prompted and follow the instructions. I will then send a connection link, that you will find into the Google Home application. You will have to log in to your CELA account. You'll only have to do this once, and you'll be all set to start enjoying the wonderful world of EDRLAB books for hours on end!\nWould you like to link your account right now?\n`; + const help = `To fully experience EDRLAB Library, and enjoy your favorite audiobooks via Google, you'll need to connect your CELA account. To do so, answer 'yes' when prompted and follow the instructions. I will then send a connection link, that you will find into the Google Home application. You will have to log in to your EDRLAB account. You'll only have to do this once, and you'll be all set to start enjoying the wonderful world of EDRLAB books for hours on end!\nWould you like to link your account right now?\n`; it('help', async () => { body.handler.name = 'home_new_user__intent__help'; diff --git a/webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts b/webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts index f22873c2..f8f7eabd 100644 --- a/webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts +++ b/webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts @@ -59,16 +59,17 @@ describe('home_new_user_maybe_later handler', () => { data.scene.next.name.should.to.be.eq('home_new_user_AccountLinking'); }); - it('no', async () => { + + it('learn more', async () => { body.handler.name = 'home_new_user_maybe_later__intent__learn_more'; body.scene.name = scene; const data = await expressMocked(body, headers); - const message = `In order to read books using the EDRLAB Library via Google, you need to be a registered EDRLAB member and link your account.\nWould you like to learn more about EDRLAB?\n`; + const message = `EDRLAB about text. Would you like to find out more about EDRLAB membership, or would you prefer to exit this skill?\n`; data.prompt.firstSimple.speech.should.to.be.eq(message); - data.scene.next.name.should.to.be.eq('home_new_user_info'); + data.scene.next.name.should.to.be.eq('info'); }); it('repeat', async () => { diff --git a/webhooks/functions/src/sdk/info.test.ts b/webhooks/functions/src/sdk/info.test.ts new file mode 100644 index 00000000..d2569d48 --- /dev/null +++ b/webhooks/functions/src/sdk/info.test.ts @@ -0,0 +1,139 @@ +import {expressMocked, shell} from '../test/utils.test'; +import * as chai from 'chai'; +// import * as sinon from 'sinon'; +import {headers, body} from './conv.test'; + + +chai.should(); + +const scene = 'info'; + +const yaml = `intentEvents: +- handler: + webhookHandler: info__intent__yes + intent: "yes" + transitionToScene: actions.scene.END_CONVERSATION +- handler: + webhookHandler: info__intent__help + intent: help +- handler: + webhookHandler: info__intent__repeat + intent: repeat +- handler: + webhookHandler: info__intent__yes + intent: membership + transitionToScene: actions.scene.END_CONVERSATION +- handler: + webhookHandler: info__intent__fallback + intent: actions.intent.NO_MATCH_1 +- handler: + webhookHandler: info__intent__fallback + intent: actions.intent.NO_MATCH_2 +- handler: + webhookHandler: info__intent__fallback_end + intent: actions.intent.NO_MATCH_FINAL +- handler: + webhookHandler: info__intent__silence + intent: actions.intent.NO_INPUT_1 +- handler: + webhookHandler: info__intent__silence + intent: actions.intent.NO_INPUT_2 +- handler: + webhookHandler: info__intent__silence_end + intent: actions.intent.NO_INPUT_FINAL +`; + +describe(scene + ' handler', () => { + describe('sdk', () => { + it('check main scene', (done) => { + shell(`cat custom/scenes/${scene}.yaml`, (stdout) => { + stdout.should.to.be.eq(yaml); + }, done); + }); + }); + + describe('app', () => { + it('yes or membership', async () => { + body.handler.name = 'info__intent__yes'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + const message = `Signing up is easy, you can head on over to the CELA online platform at 'URL'. Keep the name of your local library and your library or SQLA number handy, that's all you'll need. You can also ask for help at your local library. As soon as your membership is activated, you can come back to start using the EDRLAB library via Alexa, by saying 'Hey Google, launch EDRLAB'\n`; + data.prompt.firstSimple.speech.should.to.be.eq(message); + + data.scene.next.name.should.to.be.eq('actions.scene.END_CONVERSATION'); + }); + + it('repeat', async () => { + body.handler.name = 'info__intent__repeat'; + body.scene.name = scene; + + const message = `EDRLAB about text. Would you like to find out more about EDRLAB membership, or would you prefer to exit this skill?\n`; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + + data.scene.next.name.should.to.be.eq('info'); + }); + + const help = `If you'd like to learn more about CELA membership - you can ask me by saying 'membership', or simply say 'stop' to exit this skill. If you have any other questions, we recommend reaching out to your local library for support. I'm listening?\n`; + + it('help', async () => { + body.handler.name = 'info__intent__help'; + body.scene.name = scene; + + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('info'); + }); + + it('fallback 1 and 2', async () => { + body.handler.name = 'info__intent__help'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('info'); + }); + + it('fallback 3', async () => { + body.handler.name = 'info__intent__fallback_end'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + + // data.scene.next.name.should.to.be.eq('home_new_user'); + }); + + it('silence 1 and 2', async () => { + body.handler.name = 'info__intent__silence'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('info'); + }); + + it('silence 3', async () => { + body.handler.name = 'info__intent__fallback_end'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + + // data.scene.next.name.should.to.be.eq('home_new_user'); + }); + }); +}); diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index a77eaf96..9838d91b 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -19,7 +19,7 @@ "2": "Would you like to learn more about {{- name}}?" }, "help": { - "1": "To fully experience {{- name}} Library, and enjoy your favorite audiobooks via Google, you'll need to connect your CELA account. To do so, answer 'yes' when prompted and follow the instructions. I will then send a connection link, that you will find into the Google Home application. You will have to log in to your CELA account. You'll only have to do this once, and you'll be all set to start enjoying the wonderful world of {{- name}} books for hours on end!", + "1": "To fully experience {{- name}} Library, and enjoy your favorite audiobooks via Google, you'll need to connect your CELA account. To do so, answer 'yes' when prompted and follow the instructions. I will then send a connection link, that you will find into the Google Home application. You will have to log in to your {{- name}} account. You'll only have to do this once, and you'll be all set to start enjoying the wonderful world of {{- name}} books for hours on end!", "2": "Would you like to link your account right now?" }, "maybeLater": { @@ -32,5 +32,16 @@ "1": "You can ask me to link your account, or to learn more about {{- name}}. You can also exit this skill, by simply saying 'stop'. What would you like to do?" } }, + "info": { + "about": { + "1": "{{- name}} about text. Would you like to find out more about {{- name}} membership, or would you prefer to exit this skill?" + }, + "help": { + "1": "If you'd like to learn more about CELA membership - you can ask me by saying 'membership', or simply say 'stop' to exit this skill. If you have any other questions, we recommend reaching out to your local library for support. I'm listening?" + }, + "yesOrMembership": { + "1": "Signing up is easy, you can head on over to the CELA online platform at 'URL'. Keep the name of your local library and your library or SQLA number handy, that's all you'll need. You can also ask for help at your local library. As soon as your membership is activated, you can come back to start using the {{- name}} library via Alexa, by saying 'Hey Google, launch {{- name}}'" + } + }, "void": "need to replace this message" } \ No newline at end of file diff --git a/webhooks/functions/src/type.ts b/webhooks/functions/src/type.ts index 3826a425..ecf654b9 100644 --- a/webhooks/functions/src/type.ts +++ b/webhooks/functions/src/type.ts @@ -2,6 +2,7 @@ import { ConversationV3, ConversationV3App } from "@assistant/conversation"; import { Media } from "@assistant/conversation/dist/api/schema"; import { Machine } from "./controller/Machine"; import { TI18nKey } from "./translation"; +import { TSdkScene } from "./typings/sdkScene"; export enum MediaType { Audio = 'AUDIO', @@ -28,4 +29,6 @@ export interface IConversationV3App extends ConversationV3App TMachine | undefined | void; \ No newline at end of file +export type THandlerFn = (machine: TMachine) => TMachine | undefined | void; + +export type TSdkScene2 = TSdkScene | "actions.scene.END_CONVERSATION"; \ No newline at end of file diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index b5d1bb8f..fad6139b 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.newUser.1" | "main.welcome.newUser.2" | "main.welcome.newUser.3" | "main.welcome.user.1" | "main.welcome.user.2" | "main.welcome.user.3" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "void", + "en": "main.welcome.newUser.1" | "main.welcome.newUser.2" | "main.welcome.newUser.3" | "main.welcome.user.1" | "main.welcome.user.2" | "main.welcome.user.3" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "void", "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "en": "en:main.welcome.newUser.1" | "en:main.welcome.newUser.2" | "en:main.welcome.newUser.3" | "en:main.welcome.user.1" | "en:main.welcome.user.2" | "en:main.welcome.user.3" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:void", + "en": "en:main.welcome.newUser.1" | "en:main.welcome.newUser.2" | "en:main.welcome.newUser.3" | "en:main.welcome.user.1" | "en:main.welcome.user.2" | "en:main.welcome.user.3" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:void", "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index 4d465a9d..3971724e 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'cancel' | 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end'; +export type TSdkHandler = 'cancel' | 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end'; diff --git a/webhooks/functions/src/typings/sdkScene.d.ts b/webhooks/functions/src/typings/sdkScene.d.ts index 9cc4677e..fa500c35 100644 --- a/webhooks/functions/src/typings/sdkScene.d.ts +++ b/webhooks/functions/src/typings/sdkScene.d.ts @@ -1,4 +1,4 @@ // npm run scene-typed ; -export type TSdkScene = 'home_new_user' | 'home_new_user_AccountLinking' | 'home_new_user_info' | 'home_new_user_maybe_later' | 'home_new_user_no' | 'home_user'; +export type TSdkScene = 'home_new_user' | 'home_new_user_AccountLinking' | 'home_new_user_maybe_later' | 'home_new_user_no' | 'home_user' | 'info'; From 393e9184724e9b5e5b422fd9a4f32d36a01a90d8 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 8 Feb 2022 15:17:21 +0100 Subject: [PATCH 107/180] feat: home_new_user_no scene --- sdk/custom/scenes/home_new_user_no.yaml | 32 +++- sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 8 + webhooks/functions/src/controller/Machine.ts | 5 +- .../controller/handler/home_new_user_no.ts | 44 ++++++ .../functions/src/controller/handler/index.ts | 2 + .../functions/src/controller/handler/info.ts | 1 - .../src/sdk/home_new_user_no.test.ts | 145 ++++++++++++++++++ webhooks/functions/src/translation/en/en.json | 5 + webhooks/functions/src/typings/i18n.d.ts | 4 +- .../functions/src/typings/sdkHandler.d.ts | 2 +- 10 files changed, 240 insertions(+), 8 deletions(-) create mode 100644 webhooks/functions/src/controller/handler/home_new_user_no.ts create mode 100644 webhooks/functions/src/sdk/home_new_user_no.test.ts diff --git a/sdk/custom/scenes/home_new_user_no.yaml b/sdk/custom/scenes/home_new_user_no.yaml index 0967ef42..5df6dc72 100644 --- a/sdk/custom/scenes/home_new_user_no.yaml +++ b/sdk/custom/scenes/home_new_user_no.yaml @@ -1 +1,31 @@ -{} +intentEvents: +- handler: + webhookHandler: home_new_user_no__intent__yes + intent: "yes" +- handler: + webhookHandler: home_new_user_no__intent__no + intent: "no" +- handler: + webhookHandler: home_new_user_no__intent__repeat + intent: repeat +- handler: + webhookHandler: home_new_user_no__intent__help + intent: help +- handler: + webhookHandler: home_new_user_no__intent__fallback + intent: actions.intent.NO_MATCH_1 +- handler: + webhookHandler: home_new_user_no__intent__fallback + intent: actions.intent.NO_MATCH_2 +- handler: + webhookHandler: home_new_user_no__intent__fallback_end + intent: actions.intent.NO_MATCH_FINAL +- handler: + webhookHandler: home_new_user_no__intent__silence + intent: actions.intent.NO_INPUT_1 +- handler: + webhookHandler: home_new_user_no__intent__silence + intent: actions.intent.NO_INPUT_2 +- handler: + webhookHandler: home_new_user_no__intent__silence_end + intent: actions.intent.NO_INPUT_FINAL diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index 9837a335..49ad3ab8 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -26,6 +26,14 @@ handlers: - name: info__intent__fallback_end - name: info__intent__silence - name: info__intent__silence_end +- name: home_new_user_no__intent__yes +- name: home_new_user_no__intent__no +- name: home_new_user_no__intent__repeat +- name: home_new_user_no__intent__help +- name: home_new_user_no__intent__fallback +- name: home_new_user_no__intent__fallback_end +- name: home_new_user_no__intent__silence +- name: home_new_user_no__intent__silence_end httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index e02cc60d..460af8d2 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -1,8 +1,7 @@ import {ok} from 'assert'; import {StorageModel} from '../model/storage.model'; import {i18n, TI18n, TI18nKey} from '../translation'; -import {IConversationV3} from '../type'; -import {TSdkScene} from '../typings/sdkScene'; +import {IConversationV3, TSdkScene2} from '../type'; export class Machine { private _conv: IConversationV3; @@ -60,7 +59,7 @@ export class Machine { return this._conv.user.accountLinkingStatus; } - public set nextScene(scene: TSdkScene) { + public set nextScene(scene: TSdkScene2) { const obj = this._conv.scene; if (!obj.next) { diff --git a/webhooks/functions/src/controller/handler/home_new_user_no.ts b/webhooks/functions/src/controller/handler/home_new_user_no.ts new file mode 100644 index 00000000..e472c22c --- /dev/null +++ b/webhooks/functions/src/controller/handler/home_new_user_no.ts @@ -0,0 +1,44 @@ +import { NAME } from "../../constants"; +import { THandlerFn } from "../../type"; +import { Assistant } from "../Assistant"; +import { missing } from "./void"; + +export const home_new_user_no = (app: Assistant) => { + + app.handle("home_new_user_no__intent__fallback", help); + app.handle("home_new_user_no__intent__fallback_end", missing); + app.handle("home_new_user_no__intent__help", help); + app.handle("home_new_user_no__intent__no", no); + app.handle("home_new_user_no__intent__repeat", repeat); + app.handle("home_new_user_no__intent__silence", help); + app.handle("home_new_user_no__intent__silence_end", missing); + app.handle("home_new_user_no__intent__yes", yes); + +} + +const help: THandlerFn = (m) => { + + m.say("home_new_user_no.help.1", {name: NAME}); + + m.nextScene = "home_new_user_no"; +} + +const yes: THandlerFn = (m) => { + + m.say("info.about.1", {name: NAME}); + + m.nextScene = "info"; +} + +const no: THandlerFn = (m) => { + + m.nextScene = "actions.scene.END_CONVERSATION"; +} + +const repeat: THandlerFn = (m) => { + + m.say('home_new_user.no.1', {name: NAME}); + m.say('home_new_user.no.2', {name: NAME}); + + m.nextScene = "home_new_user_no"; +} \ No newline at end of file diff --git a/webhooks/functions/src/controller/handler/index.ts b/webhooks/functions/src/controller/handler/index.ts index b1f058b8..6bd376c0 100644 --- a/webhooks/functions/src/controller/handler/index.ts +++ b/webhooks/functions/src/controller/handler/index.ts @@ -1,6 +1,7 @@ import { Assistant } from "../Assistant"; import { home_new_user } from "./home_new_user"; import { home_new_user_maybe_later } from "./home_new_user_maybe_later"; +import { home_new_user_no } from "./home_new_user_no"; import { info } from "./info"; import { main } from "./main"; @@ -9,6 +10,7 @@ export const handler = (app = new Assistant({})) => { app.handle('main', main); home_new_user(app); + home_new_user_no(app); home_new_user_maybe_later(app); info(app); } \ No newline at end of file diff --git a/webhooks/functions/src/controller/handler/info.ts b/webhooks/functions/src/controller/handler/info.ts index 220fee33..19d2fb91 100644 --- a/webhooks/functions/src/controller/handler/info.ts +++ b/webhooks/functions/src/controller/handler/info.ts @@ -20,7 +20,6 @@ const membership: THandlerFn = (m) => { m.say('info.yesOrMembership.1', {name: NAME}); - // @ts-ignore m.nextScene = "actions.scene.END_CONVERSATION"; }; diff --git a/webhooks/functions/src/sdk/home_new_user_no.test.ts b/webhooks/functions/src/sdk/home_new_user_no.test.ts new file mode 100644 index 00000000..8e523768 --- /dev/null +++ b/webhooks/functions/src/sdk/home_new_user_no.test.ts @@ -0,0 +1,145 @@ +import {expressMocked, shell} from '../test/utils.test'; +import * as chai from 'chai'; +// import * as sinon from 'sinon'; +import {headers, body} from './conv.test'; + + +chai.should(); + +const scene = 'home_new_user_no'; + +const yaml = `intentEvents: +- handler: + webhookHandler: home_new_user_no__intent__yes + intent: "yes" +- handler: + webhookHandler: home_new_user_no__intent__no + intent: "no" +- handler: + webhookHandler: home_new_user_no__intent__repeat + intent: repeat +- handler: + webhookHandler: home_new_user_no__intent__help + intent: help +- handler: + webhookHandler: home_new_user_no__intent__fallback + intent: actions.intent.NO_MATCH_1 +- handler: + webhookHandler: home_new_user_no__intent__fallback + intent: actions.intent.NO_MATCH_2 +- handler: + webhookHandler: home_new_user_no__intent__fallback_end + intent: actions.intent.NO_MATCH_FINAL +- handler: + webhookHandler: home_new_user_no__intent__silence + intent: actions.intent.NO_INPUT_1 +- handler: + webhookHandler: home_new_user_no__intent__silence + intent: actions.intent.NO_INPUT_2 +- handler: + webhookHandler: home_new_user_no__intent__silence_end + intent: actions.intent.NO_INPUT_FINAL +`; + +describe(scene + ' handler', () => { + describe('sdk', () => { + it('check main scene', (done) => { + shell(`cat custom/scenes/${scene}.yaml`, (stdout) => { + stdout.should.to.be.eq(yaml); + }, done); + }); + }); + + describe('app', () => { + it('yes', async () => { + body.handler.name = 'home_new_user_no__intent__yes'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + const message = `EDRLAB about text. Would you like to find out more about EDRLAB membership, or would you prefer to exit this skill?\n`; + data.prompt.firstSimple.speech.should.to.be.eq(message); + + data.scene.next.name.should.to.be.eq('info'); + }); + + it('no', async () => { + body.handler.name = 'home_new_user_no__intent__no'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.scene.next.name.should.to.be.eq('actions.scene.END_CONVERSATION'); + }); + + it('repeat', async () => { + body.handler.name = 'home_new_user_no__intent__repeat'; + body.scene.name = scene; + + const message = `In order to read books using the EDRLAB Library via Google, you need to be a registered EDRLAB member and link your account.\nWould you like to learn more about EDRLAB?\n`; + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + + data.scene.next.name.should.to.be.eq('home_new_user_no'); + }); + + const help = `If you'd like to learn more about EDRLAB. You can ask me by saying 'what is EDRLAB', or simply say 'stop' to exit this app. If you have any other questions, we recommend reaching out to your local library for support. Do you want to learn more about EDRLAB or exit this app?\n`; + + it('help', async () => { + body.handler.name = 'home_new_user_no__intent__help'; + body.scene.name = scene; + + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('home_new_user_no'); + }); + + it('fallback 1 and 2', async () => { + body.handler.name = 'home_new_user_no__intent__help'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('home_new_user_no'); + }); + + it('fallback 3', async () => { + body.handler.name = 'home_new_user_no__intent__fallback_end'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + + // data.scene.next.name.should.to.be.eq('home_new_user_no'); + }); + + it('silence 1 and 2', async () => { + body.handler.name = 'home_new_user_no__intent__silence'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('home_new_user_no'); + }); + + it('silence 3', async () => { + body.handler.name = 'home_new_user_no__intent__fallback_end'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + + // data.scene.next.name.should.to.be.eq('home_new_user_no'); + }); + }); +}); diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index 9838d91b..ab76eced 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -32,6 +32,11 @@ "1": "You can ask me to link your account, or to learn more about {{- name}}. You can also exit this skill, by simply saying 'stop'. What would you like to do?" } }, + "home_new_user_no": { + "help": { + "1": "If you'd like to learn more about {{- name}}. You can ask me by saying 'what is {{- name}}', or simply say 'stop' to exit this app. If you have any other questions, we recommend reaching out to your local library for support. Do you want to learn more about {{- name}} or exit this app?" + } + }, "info": { "about": { "1": "{{- name}} about text. Would you like to find out more about {{- name}} membership, or would you prefer to exit this skill?" diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index fad6139b..ff579296 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.newUser.1" | "main.welcome.newUser.2" | "main.welcome.newUser.3" | "main.welcome.user.1" | "main.welcome.user.2" | "main.welcome.user.3" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "void", + "en": "main.welcome.newUser.1" | "main.welcome.newUser.2" | "main.welcome.newUser.3" | "main.welcome.user.1" | "main.welcome.user.2" | "main.welcome.user.3" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "void", "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "en": "en:main.welcome.newUser.1" | "en:main.welcome.newUser.2" | "en:main.welcome.newUser.3" | "en:main.welcome.user.1" | "en:main.welcome.user.2" | "en:main.welcome.user.3" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:void", + "en": "en:main.welcome.newUser.1" | "en:main.welcome.newUser.2" | "en:main.welcome.newUser.3" | "en:main.welcome.user.1" | "en:main.welcome.user.2" | "en:main.welcome.user.3" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:void", "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index 3971724e..5bb6f437 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'cancel' | 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end'; +export type TSdkHandler = 'cancel' | 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end'; From 164bf873865d1b47a6b8ef2077a0ab443894d248 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 8 Feb 2022 15:40:12 +0100 Subject: [PATCH 108/180] feat: global cancel no_match and no_input + EN/FR translation in gactions --- sdk/actions/en/actions.yaml | 2 ++ sdk/custom/global/actions.intent.CANCEL.yaml | 7 +------ sdk/custom/global/actions.intent.NO_INPUT_1.yaml | 8 +------- sdk/custom/global/actions.intent.NO_INPUT_2.yaml | 8 +------- .../global/actions.intent.NO_INPUT_FINAL.yaml | 7 ------- sdk/custom/global/actions.intent.NO_MATCH_1.yaml | 8 +------- sdk/custom/global/actions.intent.NO_MATCH_2.yaml | 8 +------- .../global/actions.intent.NO_MATCH_FINAL.yaml | 7 ------- sdk/custom/intents/en/help.yaml | 4 ++++ sdk/custom/intents/en/learn_more.yaml | 2 ++ sdk/custom/intents/en/link_account.yaml | 3 +++ sdk/custom/intents/en/maybe_later.yaml | 4 ++++ sdk/custom/intents/en/membership.yaml | 2 ++ sdk/custom/intents/en/no.yaml | 4 ++++ sdk/custom/intents/en/repeat.yaml | 3 +++ sdk/custom/intents/en/yes.yaml | 4 ++++ sdk/custom/intents/help.yaml | 5 ++--- sdk/custom/intents/learn_more.yaml | 3 ++- sdk/custom/intents/link_account.yaml | 3 +-- sdk/custom/intents/maybe_later.yaml | 2 +- sdk/custom/intents/membership.yaml | 2 +- sdk/custom/intents/no.yaml | 1 + sdk/custom/intents/repeat.yaml | 5 +---- sdk/custom/intents/yes.yaml | 5 ++--- sdk/custom/prompts/en/static_prompt_2.yaml | 6 ++++++ sdk/custom/prompts/static_prompt_2.yaml | 5 +++++ sdk/settings/en/settings.yaml | 4 ++++ sdk/settings/settings.yaml | 14 ++------------ sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 2 +- webhooks/functions/src/controller/handler/index.ts | 4 +++- 30 files changed, 65 insertions(+), 77 deletions(-) create mode 100644 sdk/actions/en/actions.yaml create mode 100644 sdk/custom/intents/en/help.yaml create mode 100644 sdk/custom/intents/en/learn_more.yaml create mode 100644 sdk/custom/intents/en/link_account.yaml create mode 100644 sdk/custom/intents/en/maybe_later.yaml create mode 100644 sdk/custom/intents/en/membership.yaml create mode 100644 sdk/custom/intents/en/no.yaml create mode 100644 sdk/custom/intents/en/repeat.yaml create mode 100644 sdk/custom/intents/en/yes.yaml create mode 100644 sdk/custom/prompts/en/static_prompt_2.yaml create mode 100644 sdk/custom/prompts/static_prompt_2.yaml create mode 100644 sdk/settings/en/settings.yaml diff --git a/sdk/actions/en/actions.yaml b/sdk/actions/en/actions.yaml new file mode 100644 index 00000000..f82f9c46 --- /dev/null +++ b/sdk/actions/en/actions.yaml @@ -0,0 +1,2 @@ +custom: + actions.intent.MAIN: {} diff --git a/sdk/custom/global/actions.intent.CANCEL.yaml b/sdk/custom/global/actions.intent.CANCEL.yaml index 22c095fb..1a60bac3 100644 --- a/sdk/custom/global/actions.intent.CANCEL.yaml +++ b/sdk/custom/global/actions.intent.CANCEL.yaml @@ -1,9 +1,4 @@ handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Au revoir et a bientôt + staticPromptName: static_prompt_2 webhookHandler: cancel transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/custom/global/actions.intent.NO_INPUT_1.yaml b/sdk/custom/global/actions.intent.NO_INPUT_1.yaml index de975f82..0967ef42 100644 --- a/sdk/custom/global/actions.intent.NO_INPUT_1.yaml +++ b/sdk/custom/global/actions.intent.NO_INPUT_1.yaml @@ -1,7 +1 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n'ai pas entendu. Que voulez-vous dire ? +{} diff --git a/sdk/custom/global/actions.intent.NO_INPUT_2.yaml b/sdk/custom/global/actions.intent.NO_INPUT_2.yaml index 59e57245..0967ef42 100644 --- a/sdk/custom/global/actions.intent.NO_INPUT_2.yaml +++ b/sdk/custom/global/actions.intent.NO_INPUT_2.yaml @@ -1,7 +1 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Que dite-vous ? +{} diff --git a/sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml b/sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml index 63087279..af0c87f2 100644 --- a/sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml +++ b/sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml @@ -1,8 +1 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: Je quitte l'application transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/custom/global/actions.intent.NO_MATCH_1.yaml b/sdk/custom/global/actions.intent.NO_MATCH_1.yaml index 166efc70..0967ef42 100644 --- a/sdk/custom/global/actions.intent.NO_MATCH_1.yaml +++ b/sdk/custom/global/actions.intent.NO_MATCH_1.yaml @@ -1,7 +1 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n'ai pas compris. Que voulez-vous dire ? +{} diff --git a/sdk/custom/global/actions.intent.NO_MATCH_2.yaml b/sdk/custom/global/actions.intent.NO_MATCH_2.yaml index deda0dc7..0967ef42 100644 --- a/sdk/custom/global/actions.intent.NO_MATCH_2.yaml +++ b/sdk/custom/global/actions.intent.NO_MATCH_2.yaml @@ -1,7 +1 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: je n'ai vraiment pas compris. Que voulez-vous dire ? +{} diff --git a/sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml b/sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml index 2f8cf92a..af0c87f2 100644 --- a/sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml +++ b/sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml @@ -1,8 +1 @@ -handler: - staticPrompt: - candidates: - - promptResponse: - firstSimple: - variants: - - speech: malheureusement je m'en vais, je ne comprend pas transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/custom/intents/en/help.yaml b/sdk/custom/intents/en/help.yaml new file mode 100644 index 00000000..13c3f3b2 --- /dev/null +++ b/sdk/custom/intents/en/help.yaml @@ -0,0 +1,4 @@ +trainingPhrases: +- help me please +- help me +- help diff --git a/sdk/custom/intents/en/learn_more.yaml b/sdk/custom/intents/en/learn_more.yaml new file mode 100644 index 00000000..a98a3043 --- /dev/null +++ b/sdk/custom/intents/en/learn_more.yaml @@ -0,0 +1,2 @@ +trainingPhrases: +- learn more diff --git a/sdk/custom/intents/en/link_account.yaml b/sdk/custom/intents/en/link_account.yaml new file mode 100644 index 00000000..3b559d4c --- /dev/null +++ b/sdk/custom/intents/en/link_account.yaml @@ -0,0 +1,3 @@ +trainingPhrases: +- link account +- i want to link my account diff --git a/sdk/custom/intents/en/maybe_later.yaml b/sdk/custom/intents/en/maybe_later.yaml new file mode 100644 index 00000000..19f5a18c --- /dev/null +++ b/sdk/custom/intents/en/maybe_later.yaml @@ -0,0 +1,4 @@ +trainingPhrases: +- later please +- later +- maybe later diff --git a/sdk/custom/intents/en/membership.yaml b/sdk/custom/intents/en/membership.yaml new file mode 100644 index 00000000..c34b6b1d --- /dev/null +++ b/sdk/custom/intents/en/membership.yaml @@ -0,0 +1,2 @@ +trainingPhrases: +- membership diff --git a/sdk/custom/intents/en/no.yaml b/sdk/custom/intents/en/no.yaml new file mode 100644 index 00000000..3de19e6f --- /dev/null +++ b/sdk/custom/intents/en/no.yaml @@ -0,0 +1,4 @@ +trainingPhrases: +- nop +- "no" +- "n" diff --git a/sdk/custom/intents/en/repeat.yaml b/sdk/custom/intents/en/repeat.yaml new file mode 100644 index 00000000..7f375617 --- /dev/null +++ b/sdk/custom/intents/en/repeat.yaml @@ -0,0 +1,3 @@ +trainingPhrases: +- repeat +- i do not understand diff --git a/sdk/custom/intents/en/yes.yaml b/sdk/custom/intents/en/yes.yaml new file mode 100644 index 00000000..60b9c8ab --- /dev/null +++ b/sdk/custom/intents/en/yes.yaml @@ -0,0 +1,4 @@ +trainingPhrases: +- "y" +- yep +- "yes" diff --git a/sdk/custom/intents/help.yaml b/sdk/custom/intents/help.yaml index 13c3f3b2..3693bbe9 100644 --- a/sdk/custom/intents/help.yaml +++ b/sdk/custom/intents/help.yaml @@ -1,4 +1,3 @@ trainingPhrases: -- help me please -- help me -- help +- aide +- aider moi diff --git a/sdk/custom/intents/learn_more.yaml b/sdk/custom/intents/learn_more.yaml index a98a3043..429fd2cb 100644 --- a/sdk/custom/intents/learn_more.yaml +++ b/sdk/custom/intents/learn_more.yaml @@ -1,2 +1,3 @@ trainingPhrases: -- learn more +- en savoir plus +- information diff --git a/sdk/custom/intents/link_account.yaml b/sdk/custom/intents/link_account.yaml index 708fe98f..e21fe370 100644 --- a/sdk/custom/intents/link_account.yaml +++ b/sdk/custom/intents/link_account.yaml @@ -1,3 +1,2 @@ trainingPhrases: -- i want to link my account -- link account +- je veux me connecter diff --git a/sdk/custom/intents/maybe_later.yaml b/sdk/custom/intents/maybe_later.yaml index 84b02acc..cec179b0 100644 --- a/sdk/custom/intents/maybe_later.yaml +++ b/sdk/custom/intents/maybe_later.yaml @@ -1,2 +1,2 @@ trainingPhrases: -- maybe later +- plus tard diff --git a/sdk/custom/intents/membership.yaml b/sdk/custom/intents/membership.yaml index c34b6b1d..bbe7b193 100644 --- a/sdk/custom/intents/membership.yaml +++ b/sdk/custom/intents/membership.yaml @@ -1,2 +1,2 @@ trainingPhrases: -- membership +- espace membre diff --git a/sdk/custom/intents/no.yaml b/sdk/custom/intents/no.yaml index 6ac8e817..47ed4273 100644 --- a/sdk/custom/intents/no.yaml +++ b/sdk/custom/intents/no.yaml @@ -1,3 +1,4 @@ trainingPhrases: - "n" +- non - "no" diff --git a/sdk/custom/intents/repeat.yaml b/sdk/custom/intents/repeat.yaml index 0f819691..bc2af48e 100644 --- a/sdk/custom/intents/repeat.yaml +++ b/sdk/custom/intents/repeat.yaml @@ -1,5 +1,2 @@ trainingPhrases: -- I do not understand -- can you repeat -- repeat please -- repeat +- répéter diff --git a/sdk/custom/intents/yes.yaml b/sdk/custom/intents/yes.yaml index 60b9c8ab..0e2cde57 100644 --- a/sdk/custom/intents/yes.yaml +++ b/sdk/custom/intents/yes.yaml @@ -1,4 +1,3 @@ trainingPhrases: -- "y" -- yep -- "yes" +- oui +- ui diff --git a/sdk/custom/prompts/en/static_prompt_2.yaml b/sdk/custom/prompts/en/static_prompt_2.yaml new file mode 100644 index 00000000..9aec5f68 --- /dev/null +++ b/sdk/custom/prompts/en/static_prompt_2.yaml @@ -0,0 +1,6 @@ +candidates: +- promptResponse: + firstSimple: + variants: + - speech: Thank you for trying the app. To pick up your reading again, come + back any time diff --git a/sdk/custom/prompts/static_prompt_2.yaml b/sdk/custom/prompts/static_prompt_2.yaml new file mode 100644 index 00000000..38ae8904 --- /dev/null +++ b/sdk/custom/prompts/static_prompt_2.yaml @@ -0,0 +1,5 @@ +candidates: +- promptResponse: + firstSimple: + variants: + - speech: merci au revoir diff --git a/sdk/settings/en/settings.yaml b/sdk/settings/en/settings.yaml new file mode 100644 index 00000000..72a8d167 --- /dev/null +++ b/sdk/settings/en/settings.yaml @@ -0,0 +1,4 @@ +localizedSettings: + displayName: edrlab + pronunciation: edrlab + voice: female_1 diff --git a/sdk/settings/settings.yaml b/sdk/settings/settings.yaml index cc631e71..f71553da 100644 --- a/sdk/settings/settings.yaml +++ b/sdk/settings/settings.yaml @@ -1,17 +1,7 @@ category: EDUCATION_AND_REFERENCE defaultLocale: fr localizedSettings: - developerEmail: dev.edrlab@gmail.com - developerName: edrlab - displayName: dev edrlab - fullDescription: lis mon live edrlab demo - privacyPolicyUrl: https://www.edrlab.org/lml-privacy-policy/ - pronunciation: dev edrlab - sampleInvocations: - - Parler avec edrlab - - Connecter avec edrlab - - Discuter avec edrlab - shortDescription: lis mon livre - smallLogoImage: https://lh3.googleusercontent.com/IPE84cRJZSbgpkLCNMhJFkP_sbh5e18cYRvn30hVHE6nYNLfQ_9a-opqTKbQNThVPUzo8sfP1_cR + displayName: edrlab + pronunciation: edrlab voice: female_1 projectId: edrlab-1 diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index 49ad3ab8..2f54560a 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -1,5 +1,4 @@ handlers: -- name: cancel - name: main - name: home_new_user__intent__help - name: home_new_user__intent__maybe_later @@ -34,6 +33,7 @@ handlers: - name: home_new_user_no__intent__fallback_end - name: home_new_user_no__intent__silence - name: home_new_user_no__intent__silence_end +- name: cancel httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/controller/handler/index.ts b/webhooks/functions/src/controller/handler/index.ts index 6bd376c0..823df477 100644 --- a/webhooks/functions/src/controller/handler/index.ts +++ b/webhooks/functions/src/controller/handler/index.ts @@ -9,8 +9,10 @@ export const handler = (app = new Assistant({})) => { app.handle('main', main); + app.handle('cancel', () => {}); + home_new_user(app); home_new_user_no(app); home_new_user_maybe_later(app); info(app); -} \ No newline at end of file +} From d876c3b1ded1890ad4f037c3a4aa2edf6be7c74a Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 8 Feb 2022 18:41:54 +0100 Subject: [PATCH 109/180] fix: home_new_user on_enter --- sdk/custom/scenes/home_new_user.yaml | 2 ++ sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 1 + .../src/controller/handler/home_new_user.ts | 12 ++++++---- .../functions/src/sdk/home_new_user.test.ts | 24 +++++++++---------- .../functions/src/typings/sdkHandler.d.ts | 2 +- 5 files changed, 23 insertions(+), 18 deletions(-) diff --git a/sdk/custom/scenes/home_new_user.yaml b/sdk/custom/scenes/home_new_user.yaml index 17efb580..b1add435 100644 --- a/sdk/custom/scenes/home_new_user.yaml +++ b/sdk/custom/scenes/home_new_user.yaml @@ -30,3 +30,5 @@ intentEvents: - handler: webhookHandler: home_new_user__intent__silence_end intent: actions.intent.NO_INPUT_FINAL +onEnter: + webhookHandler: home_new_user__on_enter diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index 2f54560a..8114a9a7 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -34,6 +34,7 @@ handlers: - name: home_new_user_no__intent__silence - name: home_new_user_no__intent__silence_end - name: cancel +- name: home_new_user__on_enter httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/controller/handler/home_new_user.ts b/webhooks/functions/src/controller/handler/home_new_user.ts index cec5b609..92760c41 100644 --- a/webhooks/functions/src/controller/handler/home_new_user.ts +++ b/webhooks/functions/src/controller/handler/home_new_user.ts @@ -5,6 +5,7 @@ import { missing } from "./void"; export const home_new_user = (app: Assistant) => { + app.handle("home_new_user__on_enter", enter); app.handle("home_new_user__intent__fallback", help); app.handle("home_new_user__intent__fallback_end", missing); app.handle("home_new_user__intent__help", help); @@ -17,6 +18,12 @@ export const home_new_user = (app: Assistant) => { } +const enter: THandlerFn = (m) => { + m.say("main.welcome.newUser.1", { name: NAME }); + m.say("main.welcome.newUser.2", { name: NAME }); + m.say("main.welcome.newUser.3"); +} + const help: THandlerFn = (m) => { m.say("home_new_user.help.1", {name: NAME}); @@ -37,7 +44,6 @@ const yes: THandlerFn = (m) => { // do nothing - } const no: THandlerFn = (m) => { @@ -50,9 +56,5 @@ const no: THandlerFn = (m) => { const repeat: THandlerFn = (m) => { - m.say("main.welcome.newUser.1", { name: NAME }); - m.say("main.welcome.newUser.2", { name: NAME }); - m.say("main.welcome.newUser.3"); - m.nextScene = "home_new_user"; } \ No newline at end of file diff --git a/webhooks/functions/src/sdk/home_new_user.test.ts b/webhooks/functions/src/sdk/home_new_user.test.ts index 4b26287b..748e264f 100644 --- a/webhooks/functions/src/sdk/home_new_user.test.ts +++ b/webhooks/functions/src/sdk/home_new_user.test.ts @@ -40,6 +40,8 @@ const yaml = `intentEvents: - handler: webhookHandler: home_new_user__intent__silence_end intent: actions.intent.NO_INPUT_FINAL +onEnter: + webhookHandler: home_new_user__on_enter `; describe('home_new_user handler', () => { @@ -52,6 +54,16 @@ describe('home_new_user handler', () => { }); describe('app', () => { + it('on enter', async () => { + body.handler.name = 'home_new_user__on_enter'; + body.scene.name = scene; + + const message = `Welcome to EDRLAB Library!\nTo fully enjoy your audiobooks and access your personal bookshelf, you will need to link your EDRLAB account.\nWould you like to do so now ?\n`; + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + + }); it('yes', async () => { body.handler.name = 'home_new_user__intent__yes'; body.scene.name = scene; @@ -76,18 +88,6 @@ describe('home_new_user handler', () => { data.scene.next.name.should.to.be.eq('home_new_user_no'); }); - it('repeat', async () => { - body.handler.name = 'home_new_user__intent__repeat'; - body.scene.name = scene; - - const message = `Welcome to EDRLAB Library!\nTo fully enjoy your audiobooks and access your personal bookshelf, you will need to link your EDRLAB account.\nWould you like to do so now ?\n`; - const data = await expressMocked(body, headers); - - data.prompt.firstSimple.speech.should.to.be.eq(message); - - data.scene.next.name.should.to.be.eq('home_new_user'); - }); - it('maybeLater', async () => { body.handler.name = 'home_new_user__intent__maybe_later'; body.scene.name = scene; diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index 5bb6f437..38fab4b5 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'cancel' | 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end'; +export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter'; From 5cb54edfeebfc29beae801d334041c341274fdf1 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 8 Feb 2022 18:47:42 +0100 Subject: [PATCH 110/180] fix: home_new_user_no --- sdk/custom/scenes/home_new_user_no.yaml | 2 ++ sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 1 + .../src/controller/handler/home_new_user_no.ts | 9 ++++++--- webhooks/functions/src/sdk/home_new_user.test.ts | 8 ++++++++ .../functions/src/sdk/home_new_user_no.test.ts | 15 ++++++++++++--- webhooks/functions/src/typings/sdkHandler.d.ts | 2 +- 6 files changed, 30 insertions(+), 7 deletions(-) diff --git a/sdk/custom/scenes/home_new_user_no.yaml b/sdk/custom/scenes/home_new_user_no.yaml index 5df6dc72..88c467da 100644 --- a/sdk/custom/scenes/home_new_user_no.yaml +++ b/sdk/custom/scenes/home_new_user_no.yaml @@ -29,3 +29,5 @@ intentEvents: - handler: webhookHandler: home_new_user_no__intent__silence_end intent: actions.intent.NO_INPUT_FINAL +onEnter: + webhookHandler: home_new_user_no__on_enter diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index 8114a9a7..2fd9b3fb 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -35,6 +35,7 @@ handlers: - name: home_new_user_no__intent__silence_end - name: cancel - name: home_new_user__on_enter +- name: home_new_user_no__on_enter httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/controller/handler/home_new_user_no.ts b/webhooks/functions/src/controller/handler/home_new_user_no.ts index e472c22c..02320075 100644 --- a/webhooks/functions/src/controller/handler/home_new_user_no.ts +++ b/webhooks/functions/src/controller/handler/home_new_user_no.ts @@ -5,6 +5,7 @@ import { missing } from "./void"; export const home_new_user_no = (app: Assistant) => { + app.handle("home_new_user_no__on_enter", enter); app.handle("home_new_user_no__intent__fallback", help); app.handle("home_new_user_no__intent__fallback_end", missing); app.handle("home_new_user_no__intent__help", help); @@ -16,6 +17,11 @@ export const home_new_user_no = (app: Assistant) => { } +const enter: THandlerFn = (m) => { + m.say('home_new_user.no.1', {name: NAME}); + m.say('home_new_user.no.2', {name: NAME}); +} + const help: THandlerFn = (m) => { m.say("home_new_user_no.help.1", {name: NAME}); @@ -37,8 +43,5 @@ const no: THandlerFn = (m) => { const repeat: THandlerFn = (m) => { - m.say('home_new_user.no.1', {name: NAME}); - m.say('home_new_user.no.2', {name: NAME}); - m.nextScene = "home_new_user_no"; } \ No newline at end of file diff --git a/webhooks/functions/src/sdk/home_new_user.test.ts b/webhooks/functions/src/sdk/home_new_user.test.ts index 748e264f..07ae752b 100644 --- a/webhooks/functions/src/sdk/home_new_user.test.ts +++ b/webhooks/functions/src/sdk/home_new_user.test.ts @@ -64,6 +64,14 @@ describe('home_new_user handler', () => { data.prompt.firstSimple.speech.should.to.be.eq(message); }); + it('repeat', async () => { + body.handler.name = 'home_new_user__intent__repeat'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.scene.next.name.should.to.be.eq('home_new_user'); + }); it('yes', async () => { body.handler.name = 'home_new_user__intent__yes'; body.scene.name = scene; diff --git a/webhooks/functions/src/sdk/home_new_user_no.test.ts b/webhooks/functions/src/sdk/home_new_user_no.test.ts index 8e523768..5f511f82 100644 --- a/webhooks/functions/src/sdk/home_new_user_no.test.ts +++ b/webhooks/functions/src/sdk/home_new_user_no.test.ts @@ -39,6 +39,8 @@ const yaml = `intentEvents: - handler: webhookHandler: home_new_user_no__intent__silence_end intent: actions.intent.NO_INPUT_FINAL +onEnter: + webhookHandler: home_new_user_no__on_enter `; describe(scene + ' handler', () => { @@ -51,6 +53,16 @@ describe(scene + ' handler', () => { }); describe('app', () => { + it('on enter', async () => { + body.handler.name = 'home_new_user_no__on_enter'; + body.scene.name = scene; + + const message = `In order to read books using the EDRLAB Library via Google, you need to be a registered EDRLAB member and link your account.\nWould you like to learn more about EDRLAB?\n`; + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + + }); it('yes', async () => { body.handler.name = 'home_new_user_no__intent__yes'; body.scene.name = scene; @@ -76,11 +88,8 @@ describe(scene + ' handler', () => { body.handler.name = 'home_new_user_no__intent__repeat'; body.scene.name = scene; - const message = `In order to read books using the EDRLAB Library via Google, you need to be a registered EDRLAB member and link your account.\nWould you like to learn more about EDRLAB?\n`; const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq(message); - data.scene.next.name.should.to.be.eq('home_new_user_no'); }); diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index 38fab4b5..18559943 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter'; +export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter'; From 718366dfba38b31e363d839a569a9158bcdf9f14 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 8 Feb 2022 18:53:50 +0100 Subject: [PATCH 111/180] fix: maybe_later and info --- .../scenes/home_new_user_maybe_later.yaml | 2 ++ sdk/custom/scenes/info.yaml | 2 ++ sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 2 ++ .../handler/home_new_user_maybe_later.ts | 9 ++++++--- .../functions/src/controller/handler/info.ts | 9 +++++---- .../src/sdk/home_new_user_maybe_later.test.ts | 17 +++++++++++++---- webhooks/functions/src/sdk/info.test.ts | 18 ++++++++++++++---- webhooks/functions/src/typings/sdkHandler.d.ts | 2 +- 8 files changed, 45 insertions(+), 16 deletions(-) diff --git a/sdk/custom/scenes/home_new_user_maybe_later.yaml b/sdk/custom/scenes/home_new_user_maybe_later.yaml index 60954de9..e16e4b41 100644 --- a/sdk/custom/scenes/home_new_user_maybe_later.yaml +++ b/sdk/custom/scenes/home_new_user_maybe_later.yaml @@ -29,3 +29,5 @@ intentEvents: - handler: webhookHandler: home_new_user_maybe_later__intent__silence_end intent: actions.intent.NO_INPUT_FINAL +onEnter: + webhookHandler: home_new_user_maybe_later__on_enter diff --git a/sdk/custom/scenes/info.yaml b/sdk/custom/scenes/info.yaml index 1d633a20..88d61bd0 100644 --- a/sdk/custom/scenes/info.yaml +++ b/sdk/custom/scenes/info.yaml @@ -31,3 +31,5 @@ intentEvents: - handler: webhookHandler: info__intent__silence_end intent: actions.intent.NO_INPUT_FINAL +onEnter: + webhookHandler: info__on_enter diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index 2fd9b3fb..692c1199 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -36,6 +36,8 @@ handlers: - name: cancel - name: home_new_user__on_enter - name: home_new_user_no__on_enter +- name: home_new_user_maybe_later__on_enter +- name: info__on_enter httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/controller/handler/home_new_user_maybe_later.ts b/webhooks/functions/src/controller/handler/home_new_user_maybe_later.ts index c091ba52..1b845186 100644 --- a/webhooks/functions/src/controller/handler/home_new_user_maybe_later.ts +++ b/webhooks/functions/src/controller/handler/home_new_user_maybe_later.ts @@ -5,6 +5,7 @@ import { missing } from "./void"; export const home_new_user_maybe_later = (app: Assistant) => { + app.handle("home_new_user_maybe_later__on_enter", enter); app.handle("home_new_user_maybe_later__intent__fallback", help); app.handle("home_new_user_maybe_later__intent__fallback_end", missing); app.handle("home_new_user_maybe_later__intent__help", help); @@ -16,6 +17,11 @@ export const home_new_user_maybe_later = (app: Assistant) => { } +const enter: THandlerFn = (m) => { + m.say("home_new_user.maybeLater.1", { name: NAME }); + m.say("home_new_user.maybeLater.2", { name: NAME }); +} + const linkAccount: THandlerFn = (m) => { m.nextScene = "home_new_user_AccountLinking"; @@ -30,9 +36,6 @@ const help: THandlerFn = (m) => { const repeat: THandlerFn = (m) => { - m.say("home_new_user.maybeLater.1", { name: NAME }); - m.say("home_new_user.maybeLater.2", { name: NAME }); - m.nextScene = "home_new_user_maybe_later"; } diff --git a/webhooks/functions/src/controller/handler/info.ts b/webhooks/functions/src/controller/handler/info.ts index 19d2fb91..bd1b4e8a 100644 --- a/webhooks/functions/src/controller/handler/info.ts +++ b/webhooks/functions/src/controller/handler/info.ts @@ -5,7 +5,7 @@ import { missing } from "./void"; export const info = (app: Assistant) => { - + app.handle("info__on_enter", enter); app.handle("info__intent__yes", membership); app.handle("info__intent__fallback", help); app.handle("info__intent__fallback_end", missing); @@ -16,6 +16,10 @@ export const info = (app: Assistant) => { } +const enter: THandlerFn = (m) => { + m.say('info.about.1', {name: NAME}); +} + const membership: THandlerFn = (m) => { m.say('info.yesOrMembership.1', {name: NAME}); @@ -31,8 +35,5 @@ const help: THandlerFn = (m) => { } const repeat: THandlerFn = (m) => { - - m.say('info.about.1', {name: NAME}); - m.nextScene = 'info'; }; diff --git a/webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts b/webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts index f8f7eabd..7a40523d 100644 --- a/webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts +++ b/webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts @@ -39,6 +39,8 @@ const yaml = `intentEvents: - handler: webhookHandler: home_new_user_maybe_later__intent__silence_end intent: actions.intent.NO_INPUT_FINAL +onEnter: + webhookHandler: home_new_user_maybe_later__on_enter `; describe('home_new_user_maybe_later handler', () => { @@ -51,6 +53,17 @@ describe('home_new_user_maybe_later handler', () => { }); describe('app', () => { + it('on enter', async () => { + body.handler.name = 'home_new_user_maybe_later__on_enter'; + body.scene.name = scene; + + const message = `Of course! you can learn more about EDRLAB or quit for now.\nWhat would you like to do?\n`; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + + }); it('link account', async () => { body.handler.name = 'home_new_user_maybe_later__intent__link_account'; body.scene.name = scene; @@ -76,12 +89,8 @@ describe('home_new_user_maybe_later handler', () => { body.handler.name = 'home_new_user_maybe_later__intent__repeat'; body.scene.name = scene; - const message = `Of course! you can learn more about EDRLAB or quit for now.\nWhat would you like to do?\n`; - const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq(message); - data.scene.next.name.should.to.be.eq('home_new_user_maybe_later'); }); diff --git a/webhooks/functions/src/sdk/info.test.ts b/webhooks/functions/src/sdk/info.test.ts index d2569d48..89a0deae 100644 --- a/webhooks/functions/src/sdk/info.test.ts +++ b/webhooks/functions/src/sdk/info.test.ts @@ -41,6 +41,8 @@ const yaml = `intentEvents: - handler: webhookHandler: info__intent__silence_end intent: actions.intent.NO_INPUT_FINAL +onEnter: + webhookHandler: info__on_enter `; describe(scene + ' handler', () => { @@ -53,6 +55,18 @@ describe(scene + ' handler', () => { }); describe('app', () => { + + it('on enter', async () => { + body.handler.name = 'info__on_enter'; + body.scene.name = scene; + + const message = `EDRLAB about text. Would you like to find out more about EDRLAB membership, or would you prefer to exit this skill?\n`; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + + }); it('yes or membership', async () => { body.handler.name = 'info__intent__yes'; body.scene.name = scene; @@ -69,12 +83,8 @@ describe(scene + ' handler', () => { body.handler.name = 'info__intent__repeat'; body.scene.name = scene; - const message = `EDRLAB about text. Would you like to find out more about EDRLAB membership, or would you prefer to exit this skill?\n`; - const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq(message); - data.scene.next.name.should.to.be.eq('info'); }); diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index 18559943..46e4711b 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter'; +export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter'; From 47fd337262c73c876bbcf0b1df32be58c05c3400 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 8 Feb 2022 18:55:23 +0100 Subject: [PATCH 112/180] chore: lint --- webhooks/functions/src/sdk/home_new_user.test.ts | 1 - webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts | 1 - webhooks/functions/src/sdk/home_new_user_no.test.ts | 1 - webhooks/functions/src/sdk/info.test.ts | 2 -- 4 files changed, 5 deletions(-) diff --git a/webhooks/functions/src/sdk/home_new_user.test.ts b/webhooks/functions/src/sdk/home_new_user.test.ts index 07ae752b..756eb60a 100644 --- a/webhooks/functions/src/sdk/home_new_user.test.ts +++ b/webhooks/functions/src/sdk/home_new_user.test.ts @@ -62,7 +62,6 @@ describe('home_new_user handler', () => { const data = await expressMocked(body, headers); data.prompt.firstSimple.speech.should.to.be.eq(message); - }); it('repeat', async () => { body.handler.name = 'home_new_user__intent__repeat'; diff --git a/webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts b/webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts index 7a40523d..fdae5ef9 100644 --- a/webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts +++ b/webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts @@ -62,7 +62,6 @@ describe('home_new_user_maybe_later handler', () => { const data = await expressMocked(body, headers); data.prompt.firstSimple.speech.should.to.be.eq(message); - }); it('link account', async () => { body.handler.name = 'home_new_user_maybe_later__intent__link_account'; diff --git a/webhooks/functions/src/sdk/home_new_user_no.test.ts b/webhooks/functions/src/sdk/home_new_user_no.test.ts index 5f511f82..b835885e 100644 --- a/webhooks/functions/src/sdk/home_new_user_no.test.ts +++ b/webhooks/functions/src/sdk/home_new_user_no.test.ts @@ -61,7 +61,6 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers); data.prompt.firstSimple.speech.should.to.be.eq(message); - }); it('yes', async () => { body.handler.name = 'home_new_user_no__intent__yes'; diff --git a/webhooks/functions/src/sdk/info.test.ts b/webhooks/functions/src/sdk/info.test.ts index 89a0deae..4215b092 100644 --- a/webhooks/functions/src/sdk/info.test.ts +++ b/webhooks/functions/src/sdk/info.test.ts @@ -55,7 +55,6 @@ describe(scene + ' handler', () => { }); describe('app', () => { - it('on enter', async () => { body.handler.name = 'info__on_enter'; body.scene.name = scene; @@ -65,7 +64,6 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers); data.prompt.firstSimple.speech.should.to.be.eq(message); - }); it('yes or membership', async () => { body.handler.name = 'info__intent__yes'; From 3dad35260a324a412c9bf835b7b29a69a2b264d6 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 8 Feb 2022 20:09:38 +0100 Subject: [PATCH 113/180] feat: home_user --- sdk/custom/intents/bookshelf.yaml | 1 + sdk/custom/intents/collections.yaml | 1 + sdk/custom/intents/search.yaml | 1 + sdk/custom/scenes/bookshelf.yaml | 1 + sdk/custom/scenes/collections.yaml | 1 + sdk/custom/scenes/home_user.yaml | 37 +++- sdk/custom/scenes/search.yaml | 1 + sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 10 ++ .../src/controller/handler/home_user.ts | 50 ++++++ .../functions/src/controller/handler/index.ts | 2 + webhooks/functions/src/sdk/home_user.test.ts | 160 ++++++++++++++++++ webhooks/functions/src/translation/en/en.json | 16 ++ webhooks/functions/src/typings/i18n.d.ts | 4 +- .../functions/src/typings/sdkHandler.d.ts | 2 +- webhooks/functions/src/typings/sdkScene.d.ts | 2 +- 15 files changed, 284 insertions(+), 5 deletions(-) create mode 100644 sdk/custom/intents/bookshelf.yaml create mode 100644 sdk/custom/intents/collections.yaml create mode 100644 sdk/custom/intents/search.yaml create mode 100644 sdk/custom/scenes/bookshelf.yaml create mode 100644 sdk/custom/scenes/collections.yaml create mode 100644 sdk/custom/scenes/search.yaml create mode 100644 webhooks/functions/src/controller/handler/home_user.ts create mode 100644 webhooks/functions/src/sdk/home_user.test.ts diff --git a/sdk/custom/intents/bookshelf.yaml b/sdk/custom/intents/bookshelf.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/sdk/custom/intents/bookshelf.yaml @@ -0,0 +1 @@ +{} diff --git a/sdk/custom/intents/collections.yaml b/sdk/custom/intents/collections.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/sdk/custom/intents/collections.yaml @@ -0,0 +1 @@ +{} diff --git a/sdk/custom/intents/search.yaml b/sdk/custom/intents/search.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/sdk/custom/intents/search.yaml @@ -0,0 +1 @@ +{} diff --git a/sdk/custom/scenes/bookshelf.yaml b/sdk/custom/scenes/bookshelf.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/sdk/custom/scenes/bookshelf.yaml @@ -0,0 +1 @@ +{} diff --git a/sdk/custom/scenes/collections.yaml b/sdk/custom/scenes/collections.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/sdk/custom/scenes/collections.yaml @@ -0,0 +1 @@ +{} diff --git a/sdk/custom/scenes/home_user.yaml b/sdk/custom/scenes/home_user.yaml index 0967ef42..88cd0ef2 100644 --- a/sdk/custom/scenes/home_user.yaml +++ b/sdk/custom/scenes/home_user.yaml @@ -1 +1,36 @@ -{} +intentEvents: +- handler: + webhookHandler: home_user__intent__help + intent: help +- handler: + webhookHandler: home_user__intent__repeat + intent: repeat +- handler: + webhookHandler: home_user__intent__bookshelf + intent: bookshelf +- handler: + webhookHandler: home_user__intent__collections + intent: collections +- handler: + webhookHandler: home_user__intent__search + intent: search +- handler: + webhookHandler: home_user__intent__fallback + intent: actions.intent.NO_MATCH_1 +- handler: + webhookHandler: home_user__intent__fallback + intent: actions.intent.NO_MATCH_2 +- handler: + webhookHandler: home_user__intent__fallback_end + intent: actions.intent.NO_MATCH_FINAL +- handler: + webhookHandler: home_user__intent__silence + intent: actions.intent.NO_INPUT_1 +- handler: + webhookHandler: home_user__intent__silence + intent: actions.intent.NO_INPUT_2 +- handler: + webhookHandler: home_user__intent__silence_end + intent: actions.intent.NO_INPUT_FINAL +onEnter: + webhookHandler: home_user__on_enter diff --git a/sdk/custom/scenes/search.yaml b/sdk/custom/scenes/search.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/sdk/custom/scenes/search.yaml @@ -0,0 +1 @@ +{} diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index 692c1199..4191a77c 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -38,6 +38,16 @@ handlers: - name: home_new_user_no__on_enter - name: home_new_user_maybe_later__on_enter - name: info__on_enter +- name: home_user__on_enter +- name: home_user__intent__help +- name: home_user__intent__repeat +- name: home_user__intent__bookshelf +- name: home_user__intent__collections +- name: home_user__intent__search +- name: home_user__intent__fallback +- name: home_user__intent__fallback_end +- name: home_user__intent__silence +- name: home_user__intent__silence_end httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/controller/handler/home_user.ts b/webhooks/functions/src/controller/handler/home_user.ts new file mode 100644 index 00000000..b017cc97 --- /dev/null +++ b/webhooks/functions/src/controller/handler/home_user.ts @@ -0,0 +1,50 @@ +import { NAME } from "../../constants"; +import { THandlerFn } from "../../type"; +import { Assistant } from "../Assistant"; +import { missing } from "./void"; + +export const home_user = (app: Assistant) => { + + app.handle("home_user__intent__search", search); + app.handle("home_user__intent__collections", collections); + app.handle("home_user__intent__bookshelf", bookshelf); + app.handle("home_user__on_enter", enter); + app.handle("home_user__intent__fallback", help); + app.handle("home_user__intent__fallback_end", missing); + app.handle("home_user__intent__help", help); + app.handle("home_user__intent__repeat", repeat); + app.handle("home_user__intent__silence", help); + app.handle("home_user__intent__silence_end", missing); + +} + +const enter: THandlerFn = (m) => { + m.say("home_user.enter.1", { name: NAME }); + m.say("home_user.enter.2", { name: NAME }); + m.say("home_user.enter.3", { name: NAME }); +} + +const search: THandlerFn = (m) => { + m.nextScene = "search"; +} + +const collections: THandlerFn = (m) => { + m.nextScene = "collections"; +} + +const bookshelf: THandlerFn = (m) => { + m.nextScene = "bookshelf"; +} + +const help: THandlerFn = (m) => { + + m.say("home_user.help.1", {name: NAME}); + m.say("home_user.help.2", {name: NAME}); + + m.nextScene = "home_user"; +} + +const repeat: THandlerFn = (m) => { + + m.nextScene = "home_user"; +} \ No newline at end of file diff --git a/webhooks/functions/src/controller/handler/index.ts b/webhooks/functions/src/controller/handler/index.ts index 823df477..8835ee13 100644 --- a/webhooks/functions/src/controller/handler/index.ts +++ b/webhooks/functions/src/controller/handler/index.ts @@ -2,6 +2,7 @@ import { Assistant } from "../Assistant"; import { home_new_user } from "./home_new_user"; import { home_new_user_maybe_later } from "./home_new_user_maybe_later"; import { home_new_user_no } from "./home_new_user_no"; +import { home_user } from "./home_user"; import { info } from "./info"; import { main } from "./main"; @@ -11,6 +12,7 @@ export const handler = (app = new Assistant({})) => { app.handle('cancel', () => {}); + home_user(app); home_new_user(app); home_new_user_no(app); home_new_user_maybe_later(app); diff --git a/webhooks/functions/src/sdk/home_user.test.ts b/webhooks/functions/src/sdk/home_user.test.ts new file mode 100644 index 00000000..1bcf3d0a --- /dev/null +++ b/webhooks/functions/src/sdk/home_user.test.ts @@ -0,0 +1,160 @@ +import {expressMocked, shell} from '../test/utils.test'; +import * as chai from 'chai'; +// import * as sinon from 'sinon'; +import {headers, body} from './conv.test'; + + +chai.should(); + +const scene = 'home_user'; + +const yaml = `intentEvents: +- handler: + webhookHandler: home_user__intent__help + intent: help +- handler: + webhookHandler: home_user__intent__repeat + intent: repeat +- handler: + webhookHandler: home_user__intent__bookshelf + intent: bookshelf +- handler: + webhookHandler: home_user__intent__collections + intent: collections +- handler: + webhookHandler: home_user__intent__search + intent: search +- handler: + webhookHandler: home_user__intent__fallback + intent: actions.intent.NO_MATCH_1 +- handler: + webhookHandler: home_user__intent__fallback + intent: actions.intent.NO_MATCH_2 +- handler: + webhookHandler: home_user__intent__fallback_end + intent: actions.intent.NO_MATCH_FINAL +- handler: + webhookHandler: home_user__intent__silence + intent: actions.intent.NO_INPUT_1 +- handler: + webhookHandler: home_user__intent__silence + intent: actions.intent.NO_INPUT_2 +- handler: + webhookHandler: home_user__intent__silence_end + intent: actions.intent.NO_INPUT_FINAL +onEnter: + webhookHandler: home_user__on_enter +`; + +describe('home_user handler', () => { + describe('sdk', () => { + it('check main scene', (done) => { + shell(`cat custom/scenes/${scene}.yaml`, (stdout) => { + stdout.should.to.be.eq(yaml); + }, done); + }); + }); + + describe('app', () => { + it('on enter', async () => { + body.handler.name = 'home_user__on_enter'; + body.scene.name = scene; + + const message = `Welcome back to your EDRLAB Library!\nCongratulations! You have succesfully linked your account and can now access all of your favorite books!\nWould you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?\n`; + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + }); + it('repeat', async () => { + body.handler.name = 'home_user__intent__repeat'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.scene.next.name.should.to.be.eq('home_user'); + }); + it('search', async () => { + body.handler.name = 'home_user__intent__search'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.scene.next.name.should.to.be.eq('search'); + }); + + it('browse collections', async () => { + body.handler.name = 'home_user__intent__collections'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.scene.next.name.should.to.be.eq('collections'); + }); + + it('bookshelf', async () => { + body.handler.name = 'home_user__intent__bookshelf'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.scene.next.name.should.to.be.eq('bookshelf'); + }); + + const help = `You can search for a specific book by title or author, browse our collections or check your bookshelf to start reading one of your preselected books.\nWhat would you like to do?\n`; + + it('help', async () => { + body.handler.name = 'home_user__intent__help'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('home_user'); + }); + + it('fallback 1 and 2', async () => { + body.handler.name = 'home_user__intent__help'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('home_user'); + }); + + it('fallback 3', async () => { + body.handler.name = 'home_user__intent__fallback_end'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + + // data.scene.next.name.should.to.be.eq('home_user'); + }); + + it('silence 1 and 2', async () => { + body.handler.name = 'home_user__intent__silence'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('home_user'); + }); + + it('silence 3', async () => { + body.handler.name = 'home_user__intent__fallback_end'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + + // data.scene.next.name.should.to.be.eq('home_user'); + }); + }); +}); diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index ab76eced..c1ed8c00 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -48,5 +48,21 @@ "1": "Signing up is easy, you can head on over to the CELA online platform at 'URL'. Keep the name of your local library and your library or SQLA number handy, that's all you'll need. You can also ask for help at your local library. As soon as your membership is activated, you can come back to start using the {{- name}} library via Alexa, by saying 'Hey Google, launch {{- name}}'" } }, + "home_user": { + "enter": { + "1": "Welcome back to your {{- name}} Library!", + "2": "Congratulations! You have succesfully linked your account and can now access all of your favorite books!", + "3": "Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?" + }, + "help": { + "1": "You can search for a specific book by title or author, browse our collections or check your bookshelf to start reading one of your preselected books.", + "2": "What would you like to do?" + } + }, + "search": { + "enter": { + "1": "Sure thing! What book or author are you looking for ?" + } + }, "void": "need to replace this message" } \ No newline at end of file diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index ff579296..c23085d4 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.newUser.1" | "main.welcome.newUser.2" | "main.welcome.newUser.3" | "main.welcome.user.1" | "main.welcome.user.2" | "main.welcome.user.3" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "void", + "en": "main.welcome.newUser.1" | "main.welcome.newUser.2" | "main.welcome.newUser.3" | "main.welcome.user.1" | "main.welcome.user.2" | "main.welcome.user.3" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.1" | "home_user.enter.2" | "home_user.enter.3" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "void", "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "en": "en:main.welcome.newUser.1" | "en:main.welcome.newUser.2" | "en:main.welcome.newUser.3" | "en:main.welcome.user.1" | "en:main.welcome.user.2" | "en:main.welcome.user.3" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:void", + "en": "en:main.welcome.newUser.1" | "en:main.welcome.newUser.2" | "en:main.welcome.newUser.3" | "en:main.welcome.user.1" | "en:main.welcome.user.2" | "en:main.welcome.user.3" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.1" | "en:home_user.enter.2" | "en:home_user.enter.3" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:void", "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index 46e4711b..a8dd14d6 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter'; +export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end'; diff --git a/webhooks/functions/src/typings/sdkScene.d.ts b/webhooks/functions/src/typings/sdkScene.d.ts index fa500c35..298ac292 100644 --- a/webhooks/functions/src/typings/sdkScene.d.ts +++ b/webhooks/functions/src/typings/sdkScene.d.ts @@ -1,4 +1,4 @@ // npm run scene-typed ; -export type TSdkScene = 'home_new_user' | 'home_new_user_AccountLinking' | 'home_new_user_maybe_later' | 'home_new_user_no' | 'home_user' | 'info'; +export type TSdkScene = 'bookshelf' | 'collections' | 'home_new_user' | 'home_new_user_AccountLinking' | 'home_new_user_maybe_later' | 'home_new_user_no' | 'home_user' | 'info' | 'search'; From 3156caa9510d213b2e6781d0ef955b7418a8d3f6 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 10 Feb 2022 18:41:32 +0100 Subject: [PATCH 114/180] feat and fix: storage add user and sessions and fixes some logic --- .../functions/src/controller/Assistant.ts | 5 + webhooks/functions/src/model/storage.dto.ts | 57 ++++- .../functions/src/model/storage.interface.ts | 19 ++ webhooks/functions/src/model/storage.model.ts | 14 +- webhooks/functions/src/model/storage.test.ts | 241 +++++++----------- webhooks/functions/src/test/utils.test.ts | 2 +- 6 files changed, 172 insertions(+), 166 deletions(-) diff --git a/webhooks/functions/src/controller/Assistant.ts b/webhooks/functions/src/controller/Assistant.ts index 3607b5d8..17b7d95b 100644 --- a/webhooks/functions/src/controller/Assistant.ts +++ b/webhooks/functions/src/controller/Assistant.ts @@ -25,6 +25,11 @@ export class Assistant { if (conv.scene.next) { conv.scene.next.name = conv.scene.name; } // loop + + // @TODO + // the catch handle must exit (go to END SCENE) + // Inform the user of the unexpected error and exit the app + // usefull with a db corruption .. let's the user delete his google personnal storage to trigger a new BearerToken }); if (storageModel) { diff --git a/webhooks/functions/src/model/storage.dto.ts b/webhooks/functions/src/model/storage.dto.ts index 976238c2..7b413a5e 100644 --- a/webhooks/functions/src/model/storage.dto.ts +++ b/webhooks/functions/src/model/storage.dto.ts @@ -1,5 +1,5 @@ import * as util from 'util'; -import {IStorage, IStoragePlayer, IStoragePlayerCurrent, IStoragePlayerHistory} from './storage.interface'; +import {ISessionScene, IStorage, IStoragePlayer, IStoragePlayerCurrent, IStoragePlayerHistory, IStorageSession, IStorageUser, TStateAuthentication} from './storage.interface'; import {classToPlain, Exclude, plainToClass, Transform, TransformationType, Type} from 'class-transformer'; import {Equals, IsBoolean, IsDate, IsNotEmpty, IsNumber, IsObject, IsOptional, IsString, IsUrl, Min, ValidateNested, validateSync} from 'class-validator'; @@ -83,6 +83,29 @@ class StoragePlayerDto implements IStoragePlayer { } } +class StorageSessionDto implements IStorageSession { + @IsObject() + @IsNotEmpty() + scene: ISessionScene; + + constructor() { + this.scene = { + 'home_user': { + state: 'DEFAULT', + }, + }; + } +} + +class StorageUserDto implements IStorageUser { + @IsNotEmpty() + authentication: TStateAuthentication; + + constructor() { + this.authentication = 'NO_LINKED'; + } +} + export class StorageDto implements IStorage { @IsNumber() @Equals(DB_VERSION) @@ -97,6 +120,18 @@ export class StorageDto implements IStorage { @ValidateNested() player: StoragePlayerDto; + @IsObject() + @IsNotEmpty() + @Type(() => StorageSessionDto) + @ValidateNested() + session: StorageSessionDto; + + @IsObject() + @IsNotEmpty() + @Type(() => StorageUserDto) + @ValidateNested() + user: StorageUserDto; + @Exclude() snapshot: IStorage; @@ -105,10 +140,12 @@ export class StorageDto implements IStorage { this.bearerToken = bearerToken; this.player = new StoragePlayerDto(); this.snapshot = classToPlain(this) as IStorage; + this.session = new StorageSessionDto(); + this.user = new StorageUserDto(); } @Exclude() - static create(data?: Record, bearerToken?: string): StorageDto { + static create(bearerToken: string, data?: Record): StorageDto { if (!data && bearerToken) { return new StorageDto(bearerToken); } @@ -116,17 +153,11 @@ export class StorageDto implements IStorage { const storage = plainToClass(StorageDto, data); const errors = validateSync(storage); - if (errors.length) { - bearerToken = typeof data?.bearerToken === 'string' ? data?.bearerToken : bearerToken; - if (!bearerToken) { - throw new Error('bearerToken is empty'); - } - - console.error('Storage DTO \'create\' errors', util.inspect(errors, {depth: 8})); - - console.error('new fresh storageDto created'); - - return new StorageDto(bearerToken); + if (errors.length > 0) { + throw new Error(JSON.stringify(errors, null, 4)); + } + if (storage.bearerToken !== bearerToken) { + throw new Error('the bearerToken doesn\'t match beetween the key and value'); } storage.snapshot = classToPlain(this) as IStorage; diff --git a/webhooks/functions/src/model/storage.interface.ts b/webhooks/functions/src/model/storage.interface.ts index 561d489b..5a23d4dc 100644 --- a/webhooks/functions/src/model/storage.interface.ts +++ b/webhooks/functions/src/model/storage.interface.ts @@ -17,8 +17,27 @@ export interface IStoragePlayer { history: Map; } +export type TStateDefault = 'DEFAULT' +export type TStateAuthentication = 'NO_LINKED' | 'NEWLY_LINKED' | 'LINKED' | TStateDefault; +export type TStateHomeUser = '' | TStateDefault; + +export interface ISessionScene { + 'home_user': { + state: TStateHomeUser, + } +} + +export interface IStorageSession { + scene: ISessionScene; +} + +export interface IStorageUser { + authentication: TStateAuthentication; +} + export interface IStorage { bearerToken: string; player: IStoragePlayer; + session: IStorageSession; } diff --git a/webhooks/functions/src/model/storage.model.ts b/webhooks/functions/src/model/storage.model.ts index 2e7a2909..d366002a 100644 --- a/webhooks/functions/src/model/storage.model.ts +++ b/webhooks/functions/src/model/storage.model.ts @@ -22,15 +22,11 @@ export class StorageModel { } public static async create(bearerToken: string) { - let store: StorageDto; - try { - const data = await pull(bearerToken); - - store = StorageDto.create(data, bearerToken); - } catch (e) { - console.error('StorageModel Create', e); - store = StorageDto.create(undefined, bearerToken); - } + const data = await pull(bearerToken); + + const store = StorageDto.create(bearerToken, data); + + // let's to cascading the storage errors accross storage -> storageModel -> Machine -> Assistant return new StorageModel(bearerToken, store); } diff --git a/webhooks/functions/src/model/storage.test.ts b/webhooks/functions/src/model/storage.test.ts index c8e45ef8..262ea7bf 100644 --- a/webhooks/functions/src/model/storage.test.ts +++ b/webhooks/functions/src/model/storage.test.ts @@ -10,10 +10,56 @@ import * as sinon from 'sinon'; import {StorageModel} from './storage.model'; import {storageModelMocked} from '../test/utils.test'; -chai.should(); +let freshData = { + dbVersion: 1, + bearerToken: 'test', + player: { + current: { + playing: false, + }, + history: { + + }, + }, + session: { + scene: { + home_user: { + state: 'DEFAULT', + }, + }, + }, + user: { + authentication: 'NO_LINKED', + }, +}; describe('storage DTO', () => { - it('create storage object', () => { + beforeEach(() => { + freshData = { + dbVersion: 1, + bearerToken: 'test', + player: { + current: { + playing: false, + }, + history: { + + }, + }, + session: { + scene: { + home_user: { + state: 'DEFAULT', + }, + }, + }, + user: { + authentication: 'NO_LINKED', + }, + }; + }); + + it('create storage object without bearerToken', () => { const obj = { dbVersion: 1, bearerToken: undefined, @@ -28,7 +74,7 @@ describe('storage DTO', () => { }, }; - assert.throws(() => StorageDto.create(obj)); + chai.expect(() => StorageDto.create('', obj)).to.throw(); }); it('create storage object failed dbversion', () => { @@ -46,11 +92,7 @@ describe('storage DTO', () => { }, }; - const instance = StorageDto.create(obj); - - assert.ok(instance instanceof StorageDto); - assert.equal(instance.dbVersion, 1); - console.log(instance); + chai.expect(() => StorageDto.create('test', obj)).to.throw(); }); it('create storage object failed dbversion and bearer', () => { @@ -68,128 +110,38 @@ describe('storage DTO', () => { }, }; - assert.throws(() => StorageDto.create(obj)); + chai.expect(() => StorageDto.create('test', obj)).to.throw(); }); it('undefined storage', () => { - const instance = StorageDto.create(undefined, 'test'); + const instance = StorageDto.create('test', undefined); - const extr = instance.extract(); - - assert.deepEqual({ - dbVersion: 1, - bearerToken: 'test', - player: { - current: { - - playing: false, - }, - history: { - - }, - }, - }, extr); + chai.expect(instance.bearerToken).to.be.eq('test'); }); it('bad validation extract', () => { - const instance = StorageDto.create(undefined, 'test'); + const instance = StorageDto.create('test'); instance.player.current.index = -34; const extr = instance.extract(); - assert.deepEqual({ - dbVersion: 1, - bearerToken: 'test', - player: { - current: { - - playing: false, - }, - history: { - - }, - }, - }, extr); - - // const instance2 = StorageDto.create(extr); - - // assert.deepEqual(instance2.selection, {}); - // assert.deepEqual(instance2.selection.url, undefined); - }); - - // it('selection validation extract', () => { - // const instance = StorageDto.create(undefined, 'test'); - - // instance.selection.url = undefined; - // // instance.selection.topUrl = "http://google.com"; - - // const extr = instance.extract(); - - // assert.deepEqual({ - // dbVersion: 1, - // bearerToken: 'test', - // player: { - // current: { - - // playing: false, - // }, - // history: { - - // }, - // }, - // selection: {}, - // }, extr); - - // const instance2 = StorageDto.create(extr); - - // assert.deepEqual(instance2.selection, {}); - // assert.deepEqual(instance2.selection.url, undefined); - // }); - - it('good validation extract', () => { - const instance = StorageDto.create(undefined, 'test'); - - instance.player.current.index = 0; - - const extr = instance.extract(); - - assert.deepEqual({ - dbVersion: 1, - bearerToken: 'test', - player: { - current: { - index: 0, - playing: false, - }, - history: { + const instance2 = StorageDto.create('test', extr); - }, - }, - }, extr); + chai.expect(instance2.player.current.index).to.be.undefined; }); it('create error', () => { const date = new Date(); - const obj = { - dbVersion: 1, - bearerToken: '123', - player: { - current: { - - playing: false, - }, - history: { - 'test': { - index: 0, - time: 0, - date: date, - }, - }, - }, + const obj = freshData; + // @ts-ignore + obj.player.history.test = { + index: 0, + time: 0, + date: date, }; - const instance = StorageDto.create(obj, 'test'); + const instance = StorageDto.create('test', obj); assert.deepEqual(instance.player.history.get('test'), { index: 0, @@ -206,32 +158,22 @@ describe('storage DTO', () => { const extr = classToPlain(instance); assert.deepEqual({ - dbVersion: 1, - bearerToken: '123', - player: { - current: { - - playing: false, - }, - history: { - test2: { - index: 0, - time: 0, - date: date, - }, - test: { - index: 0, - time: 0, - date: date, - }, - }, + test2: { + index: 0, + time: 0, + date: date, }, - }, extr); + test: { + index: 0, + time: 0, + date: date, + }, + }, extr.player.history); console.log(inspect(extr, {depth: 7})); console.log(new Date()); - const instance2 = StorageDto.create(extr, 'test'); + const instance2 = StorageDto.create('test', extr); assert.deepEqual(instance2.player.history.get('test2'), { index: 0, @@ -243,19 +185,32 @@ describe('storage DTO', () => { describe('storage Model', () => { - const freshData = { - dbVersion: 1, - bearerToken: 'test', - player: { - current: { - playing: false, - }, - history: { + chai.should(); - }, - }, - }; + beforeEach(() => { + freshData = { + dbVersion: 1, + bearerToken: 'test', + player: { + current: { + playing: false, + }, + history: { + }, + }, + session: { + scene: { + home_user: { + state: 'DEFAULT', + }, + }, + }, + user: { + authentication: 'NO_LINKED', + }, + }; + }); // @ts-ignore let {data, push, pull}: { diff --git a/webhooks/functions/src/test/utils.test.ts b/webhooks/functions/src/test/utils.test.ts index 0e09f70f..6e91880e 100644 --- a/webhooks/functions/src/test/utils.test.ts +++ b/webhooks/functions/src/test/utils.test.ts @@ -27,7 +27,7 @@ export const shell = (s: string, fn: (s: string) => void, done: (...a: any[]) => }; export const storageModelMocked = async () => { - const pull = sinon.stub().resolves({}); + const pull = sinon.stub().resolves(undefined); const push = sinon.stub(); const {StorageModel: _storageModel} = proxyquire('../model/storage.model', { From 6f82fc06b047aedc10ae96d5e3af87b2320bc502 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Fri, 11 Feb 2022 16:22:37 +0100 Subject: [PATCH 115/180] fix: new main message --- webhooks/functions/src/controller/Machine.ts | 11 ++++++++ .../src/controller/handler/home_new_user.ts | 5 ++-- .../src/controller/handler/home_user.ts | 5 ++-- .../functions/src/controller/handler/main.ts | 10 ++------ .../functions/src/model/storage.interface.ts | 1 + .../functions/src/sdk/home_new_user.test.ts | 2 +- webhooks/functions/src/sdk/home_user.test.ts | 2 +- webhooks/functions/src/sdk/main.test.ts | 6 ++--- webhooks/functions/src/translation/en/en.json | 25 +++++++++++-------- webhooks/functions/src/typings/i18n.d.ts | 4 +-- 10 files changed, 39 insertions(+), 32 deletions(-) diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 460af8d2..58c9c0a7 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -1,4 +1,5 @@ import {ok} from 'assert'; +import {TKeySessionScene} from '../model/storage.interface'; import {StorageModel} from '../model/storage.model'; import {i18n, TI18n, TI18nKey} from '../translation'; import {IConversationV3, TSdkScene2} from '../type'; @@ -67,4 +68,14 @@ export class Machine { } obj.next.name = scene; } + + public getSessionState(scene: TKeySessionScene) { + ok(this._model); + return this._model.store.session.scene[scene].state; + } + + public get authenticationState() { + ok(this._model); + return this._model.store.user.authentication; + } } diff --git a/webhooks/functions/src/controller/handler/home_new_user.ts b/webhooks/functions/src/controller/handler/home_new_user.ts index 92760c41..b4dd6b5b 100644 --- a/webhooks/functions/src/controller/handler/home_new_user.ts +++ b/webhooks/functions/src/controller/handler/home_new_user.ts @@ -19,9 +19,8 @@ export const home_new_user = (app: Assistant) => { } const enter: THandlerFn = (m) => { - m.say("main.welcome.newUser.1", { name: NAME }); - m.say("main.welcome.newUser.2", { name: NAME }); - m.say("main.welcome.newUser.3"); + m.say("home_new_user.enter.first.1", { name: NAME }); + m.say("home_new_user.enter.first.2", { name: NAME }); } const help: THandlerFn = (m) => { diff --git a/webhooks/functions/src/controller/handler/home_user.ts b/webhooks/functions/src/controller/handler/home_user.ts index b017cc97..f16711ba 100644 --- a/webhooks/functions/src/controller/handler/home_user.ts +++ b/webhooks/functions/src/controller/handler/home_user.ts @@ -19,9 +19,8 @@ export const home_user = (app: Assistant) => { } const enter: THandlerFn = (m) => { - m.say("home_user.enter.1", { name: NAME }); - m.say("home_user.enter.2", { name: NAME }); - m.say("home_user.enter.3", { name: NAME }); + m.say("home_user.enter.first.1", { name: NAME }); + m.say("home_user.enter.first.2", { name: NAME }); } const search: THandlerFn = (m) => { diff --git a/webhooks/functions/src/controller/handler/main.ts b/webhooks/functions/src/controller/handler/main.ts index 5bc9ec18..c8e732ec 100644 --- a/webhooks/functions/src/controller/handler/main.ts +++ b/webhooks/functions/src/controller/handler/main.ts @@ -8,19 +8,13 @@ export const main = (machine: TMachine) => { if (isLinked === AccountLinkingStatus.Linked) { - machine.say("main.welcome.user.1", { name: NAME}); - machine.say("main.welcome.user.2"); - machine.say("main.welcome.user.3"); + machine.say("main.welcome.linked.1", { name: NAME}); machine.nextScene = "home_user"; } else { - machine.say("main.welcome.newUser.1", { name: NAME}); - machine.say("main.welcome.newUser.2", { name: NAME}); - machine.say("main.welcome.newUser.3"); + machine.say("main.welcome.noLinked.1", { name: NAME}); machine.nextScene = "home_new_user"; } - - } \ No newline at end of file diff --git a/webhooks/functions/src/model/storage.interface.ts b/webhooks/functions/src/model/storage.interface.ts index 5a23d4dc..0b8c4e72 100644 --- a/webhooks/functions/src/model/storage.interface.ts +++ b/webhooks/functions/src/model/storage.interface.ts @@ -26,6 +26,7 @@ export interface ISessionScene { state: TStateHomeUser, } } +export type TKeySessionScene = keyof ISessionScene; export interface IStorageSession { scene: ISessionScene; diff --git a/webhooks/functions/src/sdk/home_new_user.test.ts b/webhooks/functions/src/sdk/home_new_user.test.ts index 756eb60a..56cec1f8 100644 --- a/webhooks/functions/src/sdk/home_new_user.test.ts +++ b/webhooks/functions/src/sdk/home_new_user.test.ts @@ -58,7 +58,7 @@ describe('home_new_user handler', () => { body.handler.name = 'home_new_user__on_enter'; body.scene.name = scene; - const message = `Welcome to EDRLAB Library!\nTo fully enjoy your audiobooks and access your personal bookshelf, you will need to link your EDRLAB account.\nWould you like to do so now ?\n`; + const message = `To fully enjoy your audiobooks and access your personal bookshelf, you will need to link your EDRLAB account.\nWould you like to do so now ?\n`; const data = await expressMocked(body, headers); data.prompt.firstSimple.speech.should.to.be.eq(message); diff --git a/webhooks/functions/src/sdk/home_user.test.ts b/webhooks/functions/src/sdk/home_user.test.ts index 1bcf3d0a..38228838 100644 --- a/webhooks/functions/src/sdk/home_user.test.ts +++ b/webhooks/functions/src/sdk/home_user.test.ts @@ -60,7 +60,7 @@ describe('home_user handler', () => { body.handler.name = 'home_user__on_enter'; body.scene.name = scene; - const message = `Welcome back to your EDRLAB Library!\nCongratulations! You have succesfully linked your account and can now access all of your favorite books!\nWould you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?\n`; + const message = `Congratulations! You have succesfully linked your account and can now access all of your favorite books!\nWould you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?\n`; const data = await expressMocked(body, headers); data.prompt.firstSimple.speech.should.to.be.eq(message); diff --git a/webhooks/functions/src/sdk/main.test.ts b/webhooks/functions/src/sdk/main.test.ts index 9c05d56c..16a05f36 100644 --- a/webhooks/functions/src/sdk/main.test.ts +++ b/webhooks/functions/src/sdk/main.test.ts @@ -19,7 +19,7 @@ describe('main handler', () => { body.user.accountLinkingStatus = 'ACCOUNT_LINKING_STATUS_UNSPECIFIED'; const data = await expressMocked(body, headers); - const welcomeNewUser = 'Welcome to EDRLAB Library!\nTo fully enjoy your audiobooks and access your personal bookshelf, you will need to link your EDRLAB account.\nWould you like to do so now ?\n'; + const welcomeNewUser = 'Welcome to EDRLAB Library!\n'; data.prompt.firstSimple.speech.should.to.be.eq(welcomeNewUser); @@ -30,7 +30,7 @@ describe('main handler', () => { body.user.accountLinkingStatus = 'NOT_LINKED'; const data = await expressMocked(body, headers); - const welcomeNewUser = 'Welcome to EDRLAB Library!\nTo fully enjoy your audiobooks and access your personal bookshelf, you will need to link your EDRLAB account.\nWould you like to do so now ?\n'; + const welcomeNewUser = 'Welcome to EDRLAB Library!\n'; data.prompt.firstSimple.speech.should.to.be.eq(welcomeNewUser); @@ -41,7 +41,7 @@ describe('main handler', () => { body.user.accountLinkingStatus = 'LINKED'; const data = await expressMocked(body, headers); - const welcomeUser = 'Welcome back to your EDRLAB Library!\nCongratulations! You have succesfully linked your account and can now access all of your favorite books!\nWould you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection?\n'; + const welcomeUser = 'Welcome back to your EDRLAB Library!\n'; data.prompt.firstSimple.speech.should.to.be.eq(welcomeUser); diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index c1ed8c00..95322e20 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -1,19 +1,21 @@ { "main": { "welcome": { - "newUser": { - "1": "Welcome to {{- name}} Library!", - "2": "To fully enjoy your audiobooks and access your personal bookshelf, you will need to link your {{- name}} account.", - "3": "Would you like to do so now ?" + "noLinked": { + "1": "Welcome to {{- name}} Library!" }, - "user": { - "1": "Welcome back to your {{- name}} Library!", - "2": "Congratulations! You have succesfully linked your account and can now access all of your favorite books!", - "3": "Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection?" + "linked": { + "1": "Welcome back to your {{- name}} Library!" } } }, "home_new_user": { + "enter": { + "first": { + "1": "To fully enjoy your audiobooks and access your personal bookshelf, you will need to link your {{- name}} account.", + "2": "Would you like to do so now ?" + } + }, "no": { "1": "In order to read books using the {{- name}} Library via Google, you need to be a registered {{- name}} member and link your account.", "2": "Would you like to learn more about {{- name}}?" @@ -50,9 +52,10 @@ }, "home_user": { "enter": { - "1": "Welcome back to your {{- name}} Library!", - "2": "Congratulations! You have succesfully linked your account and can now access all of your favorite books!", - "3": "Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?" + "first": { + "1": "Congratulations! You have succesfully linked your account and can now access all of your favorite books!", + "2": "Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?" + } }, "help": { "1": "You can search for a specific book by title or author, browse our collections or check your bookshelf to start reading one of your preselected books.", diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index c23085d4..854d0d3c 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.newUser.1" | "main.welcome.newUser.2" | "main.welcome.newUser.3" | "main.welcome.user.1" | "main.welcome.user.2" | "main.welcome.user.3" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.1" | "home_user.enter.2" | "home_user.enter.3" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "void", + "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.first.1" | "home_user.enter.first.2" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "void", "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "en": "en:main.welcome.newUser.1" | "en:main.welcome.newUser.2" | "en:main.welcome.newUser.3" | "en:main.welcome.user.1" | "en:main.welcome.user.2" | "en:main.welcome.user.3" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.1" | "en:home_user.enter.2" | "en:home_user.enter.3" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:void", + "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.first.1" | "en:home_user.enter.first.2" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:void", "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } From 1e6f0663893ac0dfbc9e1dd9c7f166374d155c82 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Fri, 11 Feb 2022 17:52:40 +0100 Subject: [PATCH 116/180] feat: first part home_user enter --- webhooks/functions/src/constants.ts | 2 + webhooks/functions/src/controller/Machine.ts | 90 +++++++++++++++++-- .../src/controller/handler/home_user.ts | 39 +++++++- .../functions/src/controller/handler/main.ts | 8 ++ .../functions/src/model/storage.interface.ts | 2 +- webhooks/functions/src/translation/en/en.json | 10 ++- webhooks/functions/src/type.ts | 2 +- webhooks/functions/src/typings/i18n.d.ts | 4 +- 8 files changed, 144 insertions(+), 13 deletions(-) diff --git a/webhooks/functions/src/constants.ts b/webhooks/functions/src/constants.ts index a565c27f..c862906c 100644 --- a/webhooks/functions/src/constants.ts +++ b/webhooks/functions/src/constants.ts @@ -13,7 +13,9 @@ export const DEFAULT_LANGUAGE: TDefaultLanguage = 'en'; export type TDefaultLanguage = Extract; export const PADDING = 5; +export const LAST_SEEN_THRESHOLD = 72; export const PROJECT_ID = 'edrlab-1'; + type TLang = 'fr' | 'en'; diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 58c9c0a7..7b0f0dcb 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -1,13 +1,17 @@ -import {ok} from 'assert'; -import {TKeySessionScene} from '../model/storage.interface'; -import {StorageModel} from '../model/storage.model'; -import {i18n, TI18n, TI18nKey} from '../translation'; -import {IConversationV3, TSdkScene2} from '../type'; +import { ok } from 'assert'; +import { AuthenticationStorage, http as httpOpdsFetcherParser, OpdsFetcher } from 'opds-fetcher-parser'; +import { API_BASE_URL, LAST_SEEN_THRESHOLD } from '../constants'; +import { TKeySessionScene, TStateAuthentication } from '../model/storage.interface'; +import { StorageModel } from '../model/storage.model'; +import { i18n, TI18n, TI18nKey } from '../translation'; +import { IConversationV3, TSdkScene2 } from '../type'; export class Machine { private _conv: IConversationV3; private _i18n: TI18n; private _model: StorageModel | undefined; + private _http: httpOpdsFetcherParser | undefined; + private _fetcher: OpdsFetcher | undefined; private _sayAcc: string; @@ -16,6 +20,8 @@ export class Machine { this._i18n = i18n; this._model = undefined; + this._http = undefined; + this._fetcher = undefined; this._conv = conv; this._sayAcc = ''; @@ -24,9 +30,11 @@ export class Machine { public async begin({ storageModel, bearerToken, + http, }: { storageModel?: StorageModel, bearerToken?: string, + http?: httpOpdsFetcherParser; }) { console.info('Machine BEGIN'); @@ -37,6 +45,23 @@ export class Machine { this._model = await StorageModel.create(bearerToken); } } + + if (http) { + this._http = http; + } else { + if (typeof bearerToken === "string") { + const authenticationStorage = new AuthenticationStorage(); + authenticationStorage.setAuthenticationToken({ + accessToken: bearerToken, + authenticationUrl: API_BASE_URL, + }); + this._http = new httpOpdsFetcherParser(undefined, authenticationStorage); + } + } + + if (this._http) { + this._fetcher = new OpdsFetcher(this._http); + } } public async end() { @@ -74,8 +99,63 @@ export class Machine { return this._model.store.session.scene[scene].state; } + public set authenticationState(s: TStateAuthentication) { + ok(this._model); + this._model.store.user.authentication = s; + } + public get authenticationState() { ok(this._model); return this._model.store.user.authentication; } + + public get isARegularUser() { + const lastSeenTime = this._conv.user.lastSeenTime; + if (lastSeenTime) { + + const currentDate = new Date().getTime() / 1000 / 60; + const lastSeenDate = Date.parse(lastSeenTime) / 1000 / 60; + + const hours = currentDate - lastSeenDate; + + if (hours <= LAST_SEEN_THRESHOLD) { + return true; + } + } + + return false; + } + + public get playingInProgress() { + ok(this._model); + return this._model.store.player.current.playing; + } + + public get playingNumber() { + ok(this._model); + return this._model.store.player.history.size; + } + + public async getCurrentPlayingTitleAndChapter() { + ok(this._model); + + const cur = this._model.store.player.current; + const chapter = (cur.index || 0) + 1; + const {title, author} = await this.getTitleAndAuthorFromWebpub(cur.url); + + return {chapter, title, author}; + } + + public async getTitleAndAuthorFromWebpub(url) { + const webpub = await this.wepubRequest(url); + const title = webpub?.title || "no title"; // @TODO i18n + const author = (webpub?.authors || [])[0] || ""; + return {title, author}; + } + + private async wepubRequest(url: string) { + // @TODO checks if url is valid + const webpub = await this._fetcher?.webpubRequest(url); + return webpub; + } } diff --git a/webhooks/functions/src/controller/handler/home_user.ts b/webhooks/functions/src/controller/handler/home_user.ts index f16711ba..c0632f98 100644 --- a/webhooks/functions/src/controller/handler/home_user.ts +++ b/webhooks/functions/src/controller/handler/home_user.ts @@ -18,9 +18,42 @@ export const home_user = (app: Assistant) => { } -const enter: THandlerFn = (m) => { - m.say("home_user.enter.first.1", { name: NAME }); - m.say("home_user.enter.first.2", { name: NAME }); +const enter: THandlerFn = async (m) => { + + const newlyLinked = m.authenticationState === "NEWLY_LINKED"; + + if (newlyLinked) { + m.say("home_user.enter.newlyUser.1", { name: NAME }); + m.say("home_user.enter.newlyUser.2", { name: NAME }); + } + + const regularUser = m.isARegularUser; + if (regularUser) { + // regularUser + } else { + // occasionalUser + } + + const playing = m.playingInProgress; + if (playing) { + + const {title, chapter, author} = await m.getCurrentPlayingTitleAndChapter(); + const readingNumber = m.playingNumber; + + m.say("home_user.enter.playing.1", {chapterNumber: chapter, titleAndAuthor: `${title}${author ? `, ${author}` : ''}`}); + if (readingNumber) { + m.say("home_user.enter.playing.2", {readingNumber: readingNumber}); + } + m.say("home_user.enter.playing.3"); + } else { + m.say("home_user.enter.newlyUser.2"); + } + + const state = m.getSessionState("home_user") + if (state === "REGULAR") { + // aka there are a session : the user discovered the app + m.say("home_user.enter.regular.1"); + } } const search: THandlerFn = (m) => { diff --git a/webhooks/functions/src/controller/handler/main.ts b/webhooks/functions/src/controller/handler/main.ts index c8e732ec..6d0c765a 100644 --- a/webhooks/functions/src/controller/handler/main.ts +++ b/webhooks/functions/src/controller/handler/main.ts @@ -10,11 +10,19 @@ export const main = (machine: TMachine) => { machine.say("main.welcome.linked.1", { name: NAME}); + if (machine.authenticationState === "NO_LINKED") { + machine.authenticationState = "NEWLY_LINKED"; + } else if (machine.authenticationState === "NEWLY_LINKED") { + machine.authenticationState = "LINKED"; + } // authenticationState === LINKED raise the end of the state machine + machine.nextScene = "home_user"; } else { machine.say("main.welcome.noLinked.1", { name: NAME}); + machine.authenticationState = "NO_LINKED"; + machine.nextScene = "home_new_user"; } } \ No newline at end of file diff --git a/webhooks/functions/src/model/storage.interface.ts b/webhooks/functions/src/model/storage.interface.ts index 0b8c4e72..3aac7b96 100644 --- a/webhooks/functions/src/model/storage.interface.ts +++ b/webhooks/functions/src/model/storage.interface.ts @@ -19,7 +19,7 @@ export interface IStoragePlayer { export type TStateDefault = 'DEFAULT' export type TStateAuthentication = 'NO_LINKED' | 'NEWLY_LINKED' | 'LINKED' | TStateDefault; -export type TStateHomeUser = '' | TStateDefault; +export type TStateHomeUser = 'REGULAR' | TStateDefault; export interface ISessionScene { 'home_user': { diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index 95322e20..7064a483 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -52,9 +52,17 @@ }, "home_user": { "enter": { - "first": { + "newlyUser": { "1": "Congratulations! You have succesfully linked your account and can now access all of your favorite books!", "2": "Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?" + }, + "playing": { + "1": "Last time, you read Chapter {{- chapterNumber}} of {{- titleAndAuthor}}, which you can resume where you left off.", + "2": "You are also reading {{- readingNumber}} other recent books, which you can choose from.", + "3": "You can search for a new one alltogether." + }, + "regular": { + "1": "What would you like to do?" } }, "help": { diff --git a/webhooks/functions/src/type.ts b/webhooks/functions/src/type.ts index ecf654b9..674d5025 100644 --- a/webhooks/functions/src/type.ts +++ b/webhooks/functions/src/type.ts @@ -29,6 +29,6 @@ export interface IConversationV3App extends ConversationV3App TMachine | undefined | void; +export type THandlerFn = (machine: TMachine) => TMachine | undefined | void | Promise; export type TSdkScene2 = TSdkScene | "actions.scene.END_CONVERSATION"; \ No newline at end of file diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index 854d0d3c..082593b7 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.first.1" | "home_user.enter.first.2" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "void", + "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "void", "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.first.1" | "en:home_user.enter.first.2" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:void", + "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:void", "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } From f2917f7d24324a2ba100cc2ebd8cd950633b857b Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 14 Feb 2022 13:25:36 +0100 Subject: [PATCH 117/180] feat: test home_member on-enter --- .../src/controller/handler/home_user.ts | 34 ++++++++------ .../functions/src/model/data.model.test.ts | 44 +++++++++++++++++ .../functions/src/model/storage.interface.ts | 3 +- webhooks/functions/src/model/storage.test.ts | 47 ++----------------- webhooks/functions/src/sdk/home_user.test.ts | 13 ++++- webhooks/functions/src/test/utils.test.ts | 10 ++-- 6 files changed, 87 insertions(+), 64 deletions(-) create mode 100644 webhooks/functions/src/model/data.model.test.ts diff --git a/webhooks/functions/src/controller/handler/home_user.ts b/webhooks/functions/src/controller/handler/home_user.ts index c0632f98..2f130b53 100644 --- a/webhooks/functions/src/controller/handler/home_user.ts +++ b/webhooks/functions/src/controller/handler/home_user.ts @@ -20,20 +20,21 @@ export const home_user = (app: Assistant) => { const enter: THandlerFn = async (m) => { - const newlyLinked = m.authenticationState === "NEWLY_LINKED"; + const state = m.getSessionState("home_user") + if (state === "SESSION") { + // aka there is a session : the user discovered the app + m.say("home_user.enter.regular.1"); + return; + } + + const newlyLinked = m.authenticationState === "NEWLY_LINKED"; if (newlyLinked) { m.say("home_user.enter.newlyUser.1", { name: NAME }); m.say("home_user.enter.newlyUser.2", { name: NAME }); - } - const regularUser = m.isARegularUser; - if (regularUser) { - // regularUser - } else { - // occasionalUser + return; } - const playing = m.playingInProgress; if (playing) { @@ -45,15 +46,20 @@ const enter: THandlerFn = async (m) => { m.say("home_user.enter.playing.2", {readingNumber: readingNumber}); } m.say("home_user.enter.playing.3"); - } else { - m.say("home_user.enter.newlyUser.2"); + + return ; } - const state = m.getSessionState("home_user") - if (state === "REGULAR") { - // aka there are a session : the user discovered the app - m.say("home_user.enter.regular.1"); + const regularUser = m.isARegularUser; + if (regularUser) { + // regularUser + // what is the purpose of this information ? + // @TODO ask to Maiike + } else { + // occasionalUser } + + m.say("home_user.enter.newlyUser.2"); } const search: THandlerFn = (m) => { diff --git a/webhooks/functions/src/model/data.model.test.ts b/webhooks/functions/src/model/data.model.test.ts new file mode 100644 index 00000000..60b9f01f --- /dev/null +++ b/webhooks/functions/src/model/data.model.test.ts @@ -0,0 +1,44 @@ +import { IStorage } from "./storage.interface"; + +export const freshDataClone = () => Object.assign({ + dbVersion: 1, + bearerToken: 'test', + player: { + current: { + playing: false, + }, + history: { + + }, + }, + session: { + scene: { + home_user: { + state: 'DEFAULT', + }, + }, + }, + user: { + authentication: 'NO_LINKED', + }, +}, {}); + +export const parsedDataClone = (): IStorage => ({ + bearerToken: 'test', + player: { + current: { + playing: false, + }, + history: new Map(), + }, + session: { + scene: { + home_user: { + state: 'DEFAULT', + }, + }, + }, + user: { + authentication: 'NO_LINKED', + }, +}); \ No newline at end of file diff --git a/webhooks/functions/src/model/storage.interface.ts b/webhooks/functions/src/model/storage.interface.ts index 3aac7b96..2141b7c7 100644 --- a/webhooks/functions/src/model/storage.interface.ts +++ b/webhooks/functions/src/model/storage.interface.ts @@ -19,7 +19,7 @@ export interface IStoragePlayer { export type TStateDefault = 'DEFAULT' export type TStateAuthentication = 'NO_LINKED' | 'NEWLY_LINKED' | 'LINKED' | TStateDefault; -export type TStateHomeUser = 'REGULAR' | TStateDefault; +export type TStateHomeUser = 'SESSION' | TStateDefault; export interface ISessionScene { 'home_user': { @@ -40,5 +40,6 @@ export interface IStorage { bearerToken: string; player: IStoragePlayer; session: IStorageSession; + user: IStorageUser; } diff --git a/webhooks/functions/src/model/storage.test.ts b/webhooks/functions/src/model/storage.test.ts index 262ea7bf..2457251a 100644 --- a/webhooks/functions/src/model/storage.test.ts +++ b/webhooks/functions/src/model/storage.test.ts @@ -9,54 +9,13 @@ import * as sinon from 'sinon'; import {StorageModel} from './storage.model'; import {storageModelMocked} from '../test/utils.test'; +import { freshDataClone } from './data.model.test'; -let freshData = { - dbVersion: 1, - bearerToken: 'test', - player: { - current: { - playing: false, - }, - history: { - - }, - }, - session: { - scene: { - home_user: { - state: 'DEFAULT', - }, - }, - }, - user: { - authentication: 'NO_LINKED', - }, -}; +let freshData = freshDataClone(); describe('storage DTO', () => { beforeEach(() => { - freshData = { - dbVersion: 1, - bearerToken: 'test', - player: { - current: { - playing: false, - }, - history: { - - }, - }, - session: { - scene: { - home_user: { - state: 'DEFAULT', - }, - }, - }, - user: { - authentication: 'NO_LINKED', - }, - }; + freshData = freshDataClone(); }); it('create storage object without bearerToken', () => { diff --git a/webhooks/functions/src/sdk/home_user.test.ts b/webhooks/functions/src/sdk/home_user.test.ts index 38228838..c545e8ff 100644 --- a/webhooks/functions/src/sdk/home_user.test.ts +++ b/webhooks/functions/src/sdk/home_user.test.ts @@ -2,6 +2,7 @@ import {expressMocked, shell} from '../test/utils.test'; import * as chai from 'chai'; // import * as sinon from 'sinon'; import {headers, body} from './conv.test'; +import { parsedDataClone } from '../model/data.model.test'; chai.should(); @@ -60,11 +61,21 @@ describe('home_user handler', () => { body.handler.name = 'home_user__on_enter'; body.scene.name = scene; - const message = `Congratulations! You have succesfully linked your account and can now access all of your favorite books!\nWould you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?\n`; + const message = `Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?\n`; const data = await expressMocked(body, headers); data.prompt.firstSimple.speech.should.to.be.eq(message); }); + it('on enter with session state', async () => { + body.handler.name = 'home_user__on_enter'; + body.scene.name = scene; + + const message = `What would you like to do?\n`; + const pullData = parsedDataClone(); + pullData.session.scene.home_user.state = "SESSION"; + const data = await expressMocked(body, headers, pullData); + data.prompt.firstSimple.speech.should.to.be.eq(message); + }); it('repeat', async () => { body.handler.name = 'home_user__intent__repeat'; body.scene.name = scene; diff --git a/webhooks/functions/src/test/utils.test.ts b/webhooks/functions/src/test/utils.test.ts index 6e91880e..ce478a8b 100644 --- a/webhooks/functions/src/test/utils.test.ts +++ b/webhooks/functions/src/test/utils.test.ts @@ -12,6 +12,8 @@ export const SDK_PATH = '../../sdk'; import * as httpMocks from 'node-mocks-http'; import {info} from 'firebase-functions/logger'; +import { IStorage } from '../model/storage.interface'; +import { parsedDataClone } from '../model/data.model.test'; export const defaults = { cwd: process.env.PWD + '/' + SDK_PATH, @@ -26,8 +28,8 @@ export const shell = (s: string, fn: (s: string) => void, done: (...a: any[]) => }); }; -export const storageModelMocked = async () => { - const pull = sinon.stub().resolves(undefined); +export const storageModelMocked = async (pullData: IStorage | undefined = undefined) => { + const pull = sinon.stub().resolves(pullData); const push = sinon.stub(); const {StorageModel: _storageModel} = proxyquire('../model/storage.model', { @@ -47,8 +49,8 @@ export const storageModelMocked = async () => { }; }; -export const expressMocked = async (body: JsonObject, headers: JsonObject) => { - const {data /* , push, pull*/} = await storageModelMocked(); +export const expressMocked = async (body: JsonObject, headers: JsonObject, pullData: IStorage | undefined = undefined) => { + const {data /* , push, pull*/} = await storageModelMocked(pullData); const assistant = new Assistant({storageModel: data}); From f423bd9e226533d783f01783726c2aa210c16109 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 14 Feb 2022 13:55:45 +0100 Subject: [PATCH 118/180] feat: remove the session data when it's a user new session , simulate google Actions behaviour in your database --- webhooks/functions/src/controller/Machine.ts | 29 +++++++++++++++++++ .../functions/src/model/data.model.test.ts | 1 + webhooks/functions/src/model/storage.dto.ts | 4 +++ .../functions/src/model/storage.interface.ts | 1 + webhooks/functions/src/sdk/home_user.test.ts | 29 +++++++++++++++++++ 5 files changed, 64 insertions(+) diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 7b0f0dcb..73107339 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -62,6 +62,10 @@ export class Machine { if (this._http) { this._fetcher = new OpdsFetcher(this._http); } + + // check new Session and keep or remove the data session + this.removeSessionDataWhenNewUserSession(); + } public async end() { @@ -158,4 +162,29 @@ export class Machine { const webpub = await this._fetcher?.webpubRequest(url); return webpub; } + + private removeSessionDataWhenNewUserSession() { + if (!this._model) { + return ; + } + const id = this._conv.session.id; + if (!id) { + return ; + } + const sameSession = id === this._model.store.user.sessionId; + if (sameSession) { + + console.info("MIDDLEWARE :: Session in progress"); + } else { + console.info("MIDDLEWARE :: new SESSION"); + this._model.store.session = { + scene: { + "home_user": { + state: "DEFAULT", + }, + } + }; + this._model.store.user.sessionId = id; + } + } } diff --git a/webhooks/functions/src/model/data.model.test.ts b/webhooks/functions/src/model/data.model.test.ts index 60b9f01f..201ad457 100644 --- a/webhooks/functions/src/model/data.model.test.ts +++ b/webhooks/functions/src/model/data.model.test.ts @@ -40,5 +40,6 @@ export const parsedDataClone = (): IStorage => ({ }, user: { authentication: 'NO_LINKED', + sessionId: "", }, }); \ No newline at end of file diff --git a/webhooks/functions/src/model/storage.dto.ts b/webhooks/functions/src/model/storage.dto.ts index 7b413a5e..5d18f457 100644 --- a/webhooks/functions/src/model/storage.dto.ts +++ b/webhooks/functions/src/model/storage.dto.ts @@ -101,6 +101,10 @@ class StorageUserDto implements IStorageUser { @IsNotEmpty() authentication: TStateAuthentication; + @IsOptional() + @IsString() + sessionId: string; + constructor() { this.authentication = 'NO_LINKED'; } diff --git a/webhooks/functions/src/model/storage.interface.ts b/webhooks/functions/src/model/storage.interface.ts index 2141b7c7..dcb9c3a1 100644 --- a/webhooks/functions/src/model/storage.interface.ts +++ b/webhooks/functions/src/model/storage.interface.ts @@ -34,6 +34,7 @@ export interface IStorageSession { export interface IStorageUser { authentication: TStateAuthentication; + sessionId?: string; } export interface IStorage { diff --git a/webhooks/functions/src/sdk/home_user.test.ts b/webhooks/functions/src/sdk/home_user.test.ts index c545e8ff..2ac894a9 100644 --- a/webhooks/functions/src/sdk/home_user.test.ts +++ b/webhooks/functions/src/sdk/home_user.test.ts @@ -66,13 +66,42 @@ describe('home_user handler', () => { data.prompt.firstSimple.speech.should.to.be.eq(message); }); + it('on enter with session state but new session', async () => { + body.handler.name = 'home_user__on_enter'; + body.scene.name = scene; + body.session.id = 'newSession'; // new session + + const message = `Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?\n`; + const pullData = parsedDataClone(); + pullData.session.scene.home_user.state = "SESSION"; + pullData.user.sessionId = "id"; + + const data = await expressMocked(body, headers, pullData); + data.prompt.firstSimple.speech.should.to.be.eq(message); + }); + it('on enter with session state but new session undefined so the session data is not removed', async () => { + body.handler.name = 'home_user__on_enter'; + body.scene.name = scene; + body.session.id = 'newSession'; // new session + + const message = `Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?\n`; + const pullData = parsedDataClone(); + pullData.session.scene.home_user.state = "SESSION"; + pullData.user.sessionId = "id"; + + const data = await expressMocked(body, headers, pullData); + data.prompt.firstSimple.speech.should.to.be.eq(message); + }); it('on enter with session state', async () => { body.handler.name = 'home_user__on_enter'; body.scene.name = scene; + body.session.id = "id"; const message = `What would you like to do?\n`; const pullData = parsedDataClone(); pullData.session.scene.home_user.state = "SESSION"; + pullData.user.sessionId = "id"; + const data = await expressMocked(body, headers, pullData); data.prompt.firstSimple.speech.should.to.be.eq(message); }); From e2ab99b965ed24bd4b8884e242cfcd3b37113eab Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 14 Feb 2022 13:56:20 +0100 Subject: [PATCH 119/180] lint --- webhooks/functions/src/controller/Machine.ts | 39 +++++++++---------- .../functions/src/model/data.model.test.ts | 6 +-- webhooks/functions/src/model/storage.test.ts | 2 +- webhooks/functions/src/sdk/home_user.test.ts | 16 ++++---- webhooks/functions/src/test/utils.test.ts | 3 +- 5 files changed, 31 insertions(+), 35 deletions(-) diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 73107339..e500fa91 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -1,10 +1,10 @@ -import { ok } from 'assert'; -import { AuthenticationStorage, http as httpOpdsFetcherParser, OpdsFetcher } from 'opds-fetcher-parser'; -import { API_BASE_URL, LAST_SEEN_THRESHOLD } from '../constants'; -import { TKeySessionScene, TStateAuthentication } from '../model/storage.interface'; -import { StorageModel } from '../model/storage.model'; -import { i18n, TI18n, TI18nKey } from '../translation'; -import { IConversationV3, TSdkScene2 } from '../type'; +import {ok} from 'assert'; +import {AuthenticationStorage, http as httpOpdsFetcherParser, OpdsFetcher} from 'opds-fetcher-parser'; +import {API_BASE_URL, LAST_SEEN_THRESHOLD} from '../constants'; +import {TKeySessionScene, TStateAuthentication} from '../model/storage.interface'; +import {StorageModel} from '../model/storage.model'; +import {i18n, TI18n, TI18nKey} from '../translation'; +import {IConversationV3, TSdkScene2} from '../type'; export class Machine { private _conv: IConversationV3; @@ -49,7 +49,7 @@ export class Machine { if (http) { this._http = http; } else { - if (typeof bearerToken === "string") { + if (typeof bearerToken === 'string') { const authenticationStorage = new AuthenticationStorage(); authenticationStorage.setAuthenticationToken({ accessToken: bearerToken, @@ -65,7 +65,6 @@ export class Machine { // check new Session and keep or remove the data session this.removeSessionDataWhenNewUserSession(); - } public async end() { @@ -112,11 +111,10 @@ export class Machine { ok(this._model); return this._model.store.user.authentication; } - + public get isARegularUser() { const lastSeenTime = this._conv.user.lastSeenTime; if (lastSeenTime) { - const currentDate = new Date().getTime() / 1000 / 60; const lastSeenDate = Date.parse(lastSeenTime) / 1000 / 60; @@ -152,8 +150,8 @@ export class Machine { public async getTitleAndAuthorFromWebpub(url) { const webpub = await this.wepubRequest(url); - const title = webpub?.title || "no title"; // @TODO i18n - const author = (webpub?.authors || [])[0] || ""; + const title = webpub?.title || 'no title'; // @TODO i18n + const author = (webpub?.authors || [])[0] || ''; return {title, author}; } @@ -165,24 +163,23 @@ export class Machine { private removeSessionDataWhenNewUserSession() { if (!this._model) { - return ; + return; } const id = this._conv.session.id; if (!id) { - return ; + return; } const sameSession = id === this._model.store.user.sessionId; if (sameSession) { - - console.info("MIDDLEWARE :: Session in progress"); + console.info('MIDDLEWARE :: Session in progress'); } else { - console.info("MIDDLEWARE :: new SESSION"); + console.info('MIDDLEWARE :: new SESSION'); this._model.store.session = { scene: { - "home_user": { - state: "DEFAULT", + 'home_user': { + state: 'DEFAULT', }, - } + }, }; this._model.store.user.sessionId = id; } diff --git a/webhooks/functions/src/model/data.model.test.ts b/webhooks/functions/src/model/data.model.test.ts index 201ad457..f9258425 100644 --- a/webhooks/functions/src/model/data.model.test.ts +++ b/webhooks/functions/src/model/data.model.test.ts @@ -1,4 +1,4 @@ -import { IStorage } from "./storage.interface"; +import {IStorage} from './storage.interface'; export const freshDataClone = () => Object.assign({ dbVersion: 1, @@ -40,6 +40,6 @@ export const parsedDataClone = (): IStorage => ({ }, user: { authentication: 'NO_LINKED', - sessionId: "", + sessionId: '', }, -}); \ No newline at end of file +}); diff --git a/webhooks/functions/src/model/storage.test.ts b/webhooks/functions/src/model/storage.test.ts index 2457251a..34ecbafd 100644 --- a/webhooks/functions/src/model/storage.test.ts +++ b/webhooks/functions/src/model/storage.test.ts @@ -9,7 +9,7 @@ import * as sinon from 'sinon'; import {StorageModel} from './storage.model'; import {storageModelMocked} from '../test/utils.test'; -import { freshDataClone } from './data.model.test'; +import {freshDataClone} from './data.model.test'; let freshData = freshDataClone(); diff --git a/webhooks/functions/src/sdk/home_user.test.ts b/webhooks/functions/src/sdk/home_user.test.ts index 2ac894a9..d31055e0 100644 --- a/webhooks/functions/src/sdk/home_user.test.ts +++ b/webhooks/functions/src/sdk/home_user.test.ts @@ -2,7 +2,7 @@ import {expressMocked, shell} from '../test/utils.test'; import * as chai from 'chai'; // import * as sinon from 'sinon'; import {headers, body} from './conv.test'; -import { parsedDataClone } from '../model/data.model.test'; +import {parsedDataClone} from '../model/data.model.test'; chai.should(); @@ -73,8 +73,8 @@ describe('home_user handler', () => { const message = `Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?\n`; const pullData = parsedDataClone(); - pullData.session.scene.home_user.state = "SESSION"; - pullData.user.sessionId = "id"; + pullData.session.scene.home_user.state = 'SESSION'; + pullData.user.sessionId = 'id'; const data = await expressMocked(body, headers, pullData); data.prompt.firstSimple.speech.should.to.be.eq(message); @@ -86,8 +86,8 @@ describe('home_user handler', () => { const message = `Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?\n`; const pullData = parsedDataClone(); - pullData.session.scene.home_user.state = "SESSION"; - pullData.user.sessionId = "id"; + pullData.session.scene.home_user.state = 'SESSION'; + pullData.user.sessionId = 'id'; const data = await expressMocked(body, headers, pullData); data.prompt.firstSimple.speech.should.to.be.eq(message); @@ -95,12 +95,12 @@ describe('home_user handler', () => { it('on enter with session state', async () => { body.handler.name = 'home_user__on_enter'; body.scene.name = scene; - body.session.id = "id"; + body.session.id = 'id'; const message = `What would you like to do?\n`; const pullData = parsedDataClone(); - pullData.session.scene.home_user.state = "SESSION"; - pullData.user.sessionId = "id"; + pullData.session.scene.home_user.state = 'SESSION'; + pullData.user.sessionId = 'id'; const data = await expressMocked(body, headers, pullData); data.prompt.firstSimple.speech.should.to.be.eq(message); diff --git a/webhooks/functions/src/test/utils.test.ts b/webhooks/functions/src/test/utils.test.ts index ce478a8b..5bd33ae8 100644 --- a/webhooks/functions/src/test/utils.test.ts +++ b/webhooks/functions/src/test/utils.test.ts @@ -12,8 +12,7 @@ export const SDK_PATH = '../../sdk'; import * as httpMocks from 'node-mocks-http'; import {info} from 'firebase-functions/logger'; -import { IStorage } from '../model/storage.interface'; -import { parsedDataClone } from '../model/data.model.test'; +import {IStorage} from '../model/storage.interface'; export const defaults = { cwd: process.env.PWD + '/' + SDK_PATH, From 476d9fdf2a79368b75afdfc675a6b45af2e5cab7 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 14 Feb 2022 13:58:36 +0100 Subject: [PATCH 120/180] chore --- webhooks/functions/src/test/utils.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/webhooks/functions/src/test/utils.test.ts b/webhooks/functions/src/test/utils.test.ts index 5bd33ae8..e27075a0 100644 --- a/webhooks/functions/src/test/utils.test.ts +++ b/webhooks/functions/src/test/utils.test.ts @@ -11,7 +11,6 @@ import {handler} from '../controller/handler'; export const SDK_PATH = '../../sdk'; import * as httpMocks from 'node-mocks-http'; -import {info} from 'firebase-functions/logger'; import {IStorage} from '../model/storage.interface'; export const defaults = { @@ -68,7 +67,7 @@ export const expressMocked = async (body: JsonObject, headers: JsonObject, pullD const promise = new Promise((resolve, reject) => res.on('end', () => { const data = res._getData(); - info('DATA RETURNED TO GOOGLE ASSISTANT: ', data); + console.info('DATA RETURNED TO GOOGLE ASSISTANT: ', data); if (data.error) { reject(data.error); From 605032b2286b10bb47e1f3130ff325844c07973f Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 14 Feb 2022 14:11:22 +0100 Subject: [PATCH 121/180] chore: add nyc code coverage --- webhooks/functions/package-lock.json | 1044 +++++++++++++++++++++++++- webhooks/functions/package.json | 3 +- 2 files changed, 1039 insertions(+), 8 deletions(-) diff --git a/webhooks/functions/package-lock.json b/webhooks/functions/package-lock.json index b7c26de6..2af94221 100644 --- a/webhooks/functions/package-lock.json +++ b/webhooks/functions/package-lock.json @@ -3,6 +3,15 @@ "requires": true, "lockfileVersion": 1, "dependencies": { + "@ampproject/remapping": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.1.tgz", + "integrity": "sha512-Aolwjd7HSC2PyY0fDj/wA/EimQT4HfEnFYNp5s9CQlrdhyvWTtvZ5YzrUPu6R6/1jKiUlxu8bUhkdSnKHNAHMA==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.0" + } + }, "@assistant/conversation": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/@assistant/conversation/-/conversation-3.8.1.tgz", @@ -47,6 +56,246 @@ } } }, + "@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.16.7" + } + }, + "@babel/compat-data": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", + "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==", + "dev": true + }, + "@babel/core": { + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.2.tgz", + "integrity": "sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.0.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.0", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.17.2", + "@babel/parser": "^7.17.0", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.0", + "@babel/types": "^7.17.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0" + } + }, + "@babel/generator": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.0.tgz", + "integrity": "sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw==", + "dev": true, + "requires": { + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-function-name": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-module-imports": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-module-transforms": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", + "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-simple-access": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true + }, + "@babel/helpers": { + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", + "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", + "dev": true, + "requires": { + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.0", + "@babel/types": "^7.17.0" + } + }, + "@babel/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.0.tgz", + "integrity": "sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw==", + "dev": true + }, "@babel/runtime": { "version": "7.16.3", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz", @@ -55,6 +304,53 @@ "regenerator-runtime": "^0.13.4" } }, + "@babel/template": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/traverse": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.0.tgz", + "integrity": "sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.0", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.0", + "@babel/types": "^7.17.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + }, "@cspotcode/source-map-consumer": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", @@ -310,6 +606,117 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jridgewell/resolve-uri": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", + "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", + "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", + "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -803,6 +1210,16 @@ "debug": "4" } }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -843,6 +1260,21 @@ "picomatch": "^2.0.4" } }, + "append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "requires": { + "default-require-extensions": "^3.0.0" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -1032,6 +1464,19 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "browserslist": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + } + }, "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -1057,6 +1502,18 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, + "caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "requires": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1069,6 +1526,12 @@ "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true }, + "caniuse-lite": { + "version": "1.0.30001312", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", + "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==", + "dev": true + }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -1144,6 +1607,12 @@ "validator": "^13.5.2" } }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -1187,6 +1656,12 @@ "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", "dev": true }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, "compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -1235,6 +1710,23 @@ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, + "convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, "cookie": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", @@ -1325,6 +1817,15 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "default-require-extensions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", + "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "dev": true, + "requires": { + "strip-bom": "^4.0.0" + } + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1452,6 +1953,12 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, + "electron-to-chromium": { + "version": "1.4.68", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.68.tgz", + "integrity": "sha512-cId+QwWrV8R1UawO6b9BR1hnkJ4EJPCPAr4h315vliHUtVUJDk39Sg1PMNnaWKfj5x+93ssjeJ9LKL6r8LaMiA==", + "dev": true + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -1491,6 +1998,12 @@ "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=" }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -1645,6 +2158,12 @@ "eslint-visitor-keys": "^3.0.0" } }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, "esquery": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", @@ -1929,6 +2448,17 @@ } } }, + "find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -2022,6 +2552,16 @@ "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", "dev": true }, + "foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + } + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -2047,6 +2587,12 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, + "fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true + }, "fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -2138,6 +2684,12 @@ "stream-events": "^1.0.4" } }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -2149,6 +2701,12 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, "get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -2310,12 +2868,36 @@ "integrity": "sha512-Gjzu0Xn7IagXVkSu9cSFuK1fqzwtLwFhNhVL8IFJijRNMgUttFbBSIAzKuSIrsFMO1+g1RlsoN49zPIbwPDMGQ==", "optional": true }, + "hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "requires": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, "http-errors": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", @@ -2415,6 +2997,12 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -2574,6 +3162,96 @@ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "requires": { + "append-transform": "^2.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + } + }, + "istanbul-lib-processinfo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", + "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.0", + "istanbul-lib-coverage": "^3.0.0-alpha.1", + "make-dir": "^3.0.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^3.3.3" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "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 + } + } + }, + "istanbul-reports": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", + "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, "jose": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.5.tgz", @@ -2582,6 +3260,12 @@ "@panva/asn1.js": "^1.0.0" } }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -2596,6 +3280,12 @@ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, "json-bigint": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", @@ -2625,6 +3315,15 @@ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -2775,6 +3474,12 @@ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -2896,7 +3601,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "optional": true, "requires": { "semver": "^6.0.0" } @@ -3167,6 +3871,21 @@ } } }, + "node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "requires": { + "process-on-spawn": "^1.0.0" + } + }, + "node-releases": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", + "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", + "dev": true + }, "node-stream-zip": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.15.0.tgz", @@ -3178,6 +3897,155 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, + "nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "requires": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -3253,6 +4121,33 @@ "p-limit": "^3.0.2" } }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -3317,12 +4212,66 @@ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + } + } + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -3334,6 +4283,15 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "requires": { + "fromentries": "^1.2.0" + } + }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -3643,6 +4601,15 @@ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -3705,6 +4672,12 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, "resolve": { "version": "1.22.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", @@ -3775,8 +4748,7 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "optional": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, "send": { "version": "0.17.1", @@ -3845,6 +4817,12 @@ "send": "0.17.1" } }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", @@ -3873,8 +4851,7 @@ "signal-exit": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "optional": true + "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==" }, "sinon": { "version": "13.0.1", @@ -3918,6 +4895,32 @@ "integrity": "sha1-EMCI2LWOsHazIpu1oE4jLOEmQi0=", "optional": true }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "requires": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, "sshpk": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", @@ -3991,6 +4994,12 @@ "ansi-regex": "^5.0.1" } }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -4039,12 +5048,29 @@ "uuid": "^8.0.0" } }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -4367,7 +5393,6 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "optional": true, "requires": { "is-typedarray": "^1.0.0" } @@ -4567,6 +5592,12 @@ "isexe": "^2.0.0" } }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -4598,7 +5629,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "optional": true, "requires": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index 0689500e..d509325d 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -8,7 +8,7 @@ "deploy": "firebase deploy --only functions", "logs": "firebase functions:log", "build": "tsc", - "test:run": "mocha --recursive --require ts-node/register", + "test:run": "nyc mocha --recursive --require ts-node/register", "test": "npm run test:run -- src/**/*.test.ts", "lint": "eslint src/**/*.ts", "lint:fix": "eslint src/**/*.ts --fix", @@ -45,6 +45,7 @@ "firebase-functions-test": "^0.2.0", "mocha": "^9.1.3", "node-mocks-http": "^1.11.0", + "nyc": "^15.1.0", "proxyquire": "^2.1.3", "rimraf": "^3.0.2", "sinon": "^13.0.1", From 4038e1b2a6e34980f55bbb6f627b3ea1f49827d6 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 14 Feb 2022 15:30:40 +0100 Subject: [PATCH 122/180] feat: test home_user on-enter playing --- webhooks/functions/package.json | 4 +- .../functions/src/controller/Assistant.ts | 10 ++- webhooks/functions/src/controller/Machine.ts | 17 ++--- .../src/controller/handler/home_user.ts | 1 + webhooks/functions/src/sdk/home_user.test.ts | 63 +++++++++++++++++++ webhooks/functions/src/test/utils.test.ts | 18 +++++- 6 files changed, 97 insertions(+), 16 deletions(-) diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index d509325d..ea5c365f 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -8,8 +8,8 @@ "deploy": "firebase deploy --only functions", "logs": "firebase functions:log", "build": "tsc", - "test:run": "nyc mocha --recursive --require ts-node/register", - "test": "npm run test:run -- src/**/*.test.ts", + "test:run": "mocha --recursive --require ts-node/register", + "test": "nyc npm run test:run -- src/**/*.test.ts", "lint": "eslint src/**/*.ts", "lint:fix": "eslint src/**/*.ts --fix", "scene-typed": "echo \"// npm run scene-typed \n\n\nexport type TSdkScene = \"$(for I in `ls ../../sdk/custom/scenes | cut -d \".\" -f1`; do echo \"'$I' |\"; done) | sed 's/..$/;/' > src/typings/sdkScene.d.ts", diff --git a/webhooks/functions/src/controller/Assistant.ts b/webhooks/functions/src/controller/Assistant.ts index 17b7d95b..1bd7c181 100644 --- a/webhooks/functions/src/controller/Assistant.ts +++ b/webhooks/functions/src/controller/Assistant.ts @@ -1,4 +1,5 @@ import {BaseApp, conversation, ConversationV3, ConversationV3App, OmniHandler} from '@assistant/conversation'; +import {OpdsFetcher} from 'opds-fetcher-parser'; import {PROJECT_ID} from '../constants'; import {StorageModel} from '../model/storage.model'; import {THandlerFn} from '../type'; @@ -8,11 +9,14 @@ import {Machine} from './Machine'; export class Assistant { private _app: OmniHandler & BaseApp & ConversationV3App; private _storageModel: StorageModel | undefined; + private _fetcher: OpdsFetcher | undefined; constructor({ storageModel, + fetcher, }: { storageModel?: StorageModel, + fetcher?: OpdsFetcher, }) { this._app = conversation({ verification: process.env['NODE_ENV'] === 'PRODUCTION' ? PROJECT_ID : undefined, @@ -36,6 +40,10 @@ export class Assistant { this._storageModel = storageModel; } + if (fetcher) { + this._fetcher = fetcher; + } + // app.middleware((_conv, _framework) => {}); } @@ -44,7 +52,7 @@ export class Assistant { const machine = new Machine(conv); const bearerToken = conv.user.params.bearerToken; - await machine.begin({bearerToken, storageModel: this._storageModel}); + await machine.begin({bearerToken, storageModel: this._storageModel, fetcher: this._fetcher}); await Promise.resolve(fn(machine)); diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index e500fa91..0b3b6acb 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -10,7 +10,6 @@ export class Machine { private _conv: IConversationV3; private _i18n: TI18n; private _model: StorageModel | undefined; - private _http: httpOpdsFetcherParser | undefined; private _fetcher: OpdsFetcher | undefined; private _sayAcc: string; @@ -20,7 +19,6 @@ export class Machine { this._i18n = i18n; this._model = undefined; - this._http = undefined; this._fetcher = undefined; this._conv = conv; @@ -30,11 +28,11 @@ export class Machine { public async begin({ storageModel, bearerToken, - http, + fetcher, }: { storageModel?: StorageModel, bearerToken?: string, - http?: httpOpdsFetcherParser; + fetcher?: OpdsFetcher; }) { console.info('Machine BEGIN'); @@ -46,8 +44,8 @@ export class Machine { } } - if (http) { - this._http = http; + if (fetcher) { + this._fetcher = fetcher; } else { if (typeof bearerToken === 'string') { const authenticationStorage = new AuthenticationStorage(); @@ -55,14 +53,11 @@ export class Machine { accessToken: bearerToken, authenticationUrl: API_BASE_URL, }); - this._http = new httpOpdsFetcherParser(undefined, authenticationStorage); + const http = new httpOpdsFetcherParser(undefined, authenticationStorage); + this._fetcher = new OpdsFetcher(http); } } - if (this._http) { - this._fetcher = new OpdsFetcher(this._http); - } - // check new Session and keep or remove the data session this.removeSessionDataWhenNewUserSession(); } diff --git a/webhooks/functions/src/controller/handler/home_user.ts b/webhooks/functions/src/controller/handler/home_user.ts index 2f130b53..d61f1a4f 100644 --- a/webhooks/functions/src/controller/handler/home_user.ts +++ b/webhooks/functions/src/controller/handler/home_user.ts @@ -46,6 +46,7 @@ const enter: THandlerFn = async (m) => { m.say("home_user.enter.playing.2", {readingNumber: readingNumber}); } m.say("home_user.enter.playing.3"); + m.say("home_user.enter.regular.1"); return ; } diff --git a/webhooks/functions/src/sdk/home_user.test.ts b/webhooks/functions/src/sdk/home_user.test.ts index d31055e0..79b891aa 100644 --- a/webhooks/functions/src/sdk/home_user.test.ts +++ b/webhooks/functions/src/sdk/home_user.test.ts @@ -3,6 +3,7 @@ import * as chai from 'chai'; // import * as sinon from 'sinon'; import {headers, body} from './conv.test'; import {parsedDataClone} from '../model/data.model.test'; +import {IWebPubView} from 'opds-fetcher-parser/build/src/interface/webpub'; chai.should(); @@ -105,6 +106,68 @@ describe('home_user handler', () => { const data = await expressMocked(body, headers, pullData); data.prompt.firstSimple.speech.should.to.be.eq(message); }); + it('on enter with a current playing no history', async () => { + body.handler.name = 'home_user__on_enter'; + body.scene.name = scene; + + const message = `Last time, you read Chapter 10 of my title, hello, which you can resume where you left off.\nYou can search for a new one alltogether.\nWhat would you like to do?\n`; + const pullData = parsedDataClone(); + pullData.player.current.index = 9; + pullData.player.current.url = 'https://my.url'; + pullData.player.current.time = 0; + pullData.player.current.playing = true; + + + const webpub: Partial = { + title: 'my title', + authors: [ + 'hello', + 'world', + ], + }; + + const data = await expressMocked(body, headers, pullData, undefined, webpub); + console.log(JSON.stringify(data, null, 4)); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + }); + it('on enter with a current playing and history', async () => { + body.handler.name = 'home_user__on_enter'; + body.scene.name = scene; + + const message = `Last time, you read Chapter 10 of my title, hello, which you can resume where you left off.\nYou are also reading 4 other recent books, which you can choose from.\nYou can search for a new one alltogether.\nWhat would you like to do?\n`; + const pullData = parsedDataClone(); + pullData.player.current.index = 9; + pullData.player.current.url = 'https://my.url'; + pullData.player.current.time = 0; + pullData.player.current.playing = true; + + pullData.player.history = { + // @ts-ignore + 1: {index: 0, time: 0, date: new Date()}, + 2: {index: 0, time: 0, date: new Date()}, + 3: {index: 0, time: 0, date: new Date()}, + 4: {index: 0, time: 0, date: new Date()}, + }; + // pullData.player.history.set("1", {index: 0, time: 0, date: new Date()}); + // pullData.player.history.set("2", {index: 0, time: 0, date: new Date()}); + // pullData.player.history.set("3", {index: 0, time: 0, date: new Date()}); + // pullData.player.history.set("4", {index: 0, time: 0, date: new Date()}); + + const webpub: Partial = { + title: 'my title', + authors: [ + 'hello', + 'world', + ], + }; + + const data = await expressMocked(body, headers, pullData, undefined, webpub); + console.log(JSON.stringify(data, null, 4)); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + }); + it('repeat', async () => { body.handler.name = 'home_user__intent__repeat'; body.scene.name = scene; diff --git a/webhooks/functions/src/test/utils.test.ts b/webhooks/functions/src/test/utils.test.ts index e27075a0..6de162f1 100644 --- a/webhooks/functions/src/test/utils.test.ts +++ b/webhooks/functions/src/test/utils.test.ts @@ -12,6 +12,8 @@ export const SDK_PATH = '../../sdk'; import * as httpMocks from 'node-mocks-http'; import {IStorage} from '../model/storage.interface'; +import {OpdsFetcher} from 'opds-fetcher-parser'; +import {IWebPubView} from 'opds-fetcher-parser/build/src/interface/webpub'; export const defaults = { cwd: process.env.PWD + '/' + SDK_PATH, @@ -47,10 +49,22 @@ export const storageModelMocked = async (pullData: IStorage | undefined = undefi }; }; -export const expressMocked = async (body: JsonObject, headers: JsonObject, pullData: IStorage | undefined = undefined) => { +export const fetcherMocked = (feed?: any, webpub?: Partial) => { + const fetcher = sinon.createStubInstance(OpdsFetcher, { + // @ts-ignore + feedRequest: sinon.stub().returns(Promise.resolve(feed)), + // @ts-ignore + webpubRequest: sinon.stub().returns(Promise.resolve(webpub)), + }); + + return fetcher; +}; + +export const expressMocked = async (body: JsonObject, headers: JsonObject, pullData: IStorage | undefined = undefined, feed: any | undefined = undefined, webpub: Partial | undefined = undefined) => { const {data /* , push, pull*/} = await storageModelMocked(pullData); + const fetcher = fetcherMocked(feed, webpub) as unknown as OpdsFetcher; - const assistant = new Assistant({storageModel: data}); + const assistant = new Assistant({storageModel: data, fetcher}); handler(assistant); From 50503e4e2babd91f2cb94746bb1d5fe92fb1ac0c Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 14 Feb 2022 16:34:38 +0100 Subject: [PATCH 123/180] feat: selection first step --- sdk/custom/scenes/bookshelf.yaml | 3 ++- sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 10 ++++++++++ .../functions/src/controller/handler/index.ts | 2 ++ webhooks/functions/src/translation/en/en.json | 17 +++++++++++++++++ webhooks/functions/src/typings/i18n.d.ts | 4 ++-- webhooks/functions/src/typings/sdkHandler.d.ts | 2 +- webhooks/functions/src/typings/sdkScene.d.ts | 2 +- 7 files changed, 35 insertions(+), 5 deletions(-) diff --git a/sdk/custom/scenes/bookshelf.yaml b/sdk/custom/scenes/bookshelf.yaml index 0967ef42..cddcd1bb 100644 --- a/sdk/custom/scenes/bookshelf.yaml +++ b/sdk/custom/scenes/bookshelf.yaml @@ -1 +1,2 @@ -{} +onEnter: + webhookHandler: bookshelf__on_enter diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index 4191a77c..4f5807a7 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -48,6 +48,16 @@ handlers: - name: home_user__intent__fallback_end - name: home_user__intent__silence - name: home_user__intent__silence_end +- name: bookshelf__on_enter +- name: selection__on_enter +- name: selection__intent__selects_book +- name: selection__intent__repeat +- name: selection__intent__another_one +- name: selection__intent__help +- name: selection__intent__fallback +- name: selection__intent__fallback_end +- name: selection__intent__silence +- name: selection__intent__silence_end httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/controller/handler/index.ts b/webhooks/functions/src/controller/handler/index.ts index 8835ee13..41d834b4 100644 --- a/webhooks/functions/src/controller/handler/index.ts +++ b/webhooks/functions/src/controller/handler/index.ts @@ -5,6 +5,7 @@ import { home_new_user_no } from "./home_new_user_no"; import { home_user } from "./home_user"; import { info } from "./info"; import { main } from "./main"; +import { selection } from "./selection"; export const handler = (app = new Assistant({})) => { @@ -17,4 +18,5 @@ export const handler = (app = new Assistant({})) => { home_new_user_no(app); home_new_user_maybe_later(app); info(app); + selection(app); } diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index 7064a483..0b0a11c3 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -75,5 +75,22 @@ "1": "Sure thing! What book or author are you looking for ?" } }, + "selection": { + "enter": { + "bookshelf": "Here are the first {{- number}} titles on your bookshelf:", + "common": { + "1": "Pick one of these books by saying their letter, or ask for their summary by saying 'Summary of A', for example.", + "2": "{{- letter}}. {{- title}}", + "3": "Which one would you like to start reading? Or perhaps you'd like to explore the other titles on your bookshelf?" + }, + "empty": { + "1": "Uh Oh! Nothing to read here quite yet. Not to worry though, we can fix that right away! Would you like to browse our collections? Or perhaps you'd like to search for a specific book by author or book title?" + } + }, + "help": { + "1": "Pick one out of 3 titles by mentioning their letter, A - B or C, or ask for their summary by saying 'Summary of A'. You can also ask for 'another one' or directly search by genre, author or book title.", + "2": "What would you like to do?" + } + }, "void": "need to replace this message" } \ No newline at end of file diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index 082593b7..c8fade92 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "void", + "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "selection.enter.bookshelf" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "void", "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:void", + "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:selection.enter.bookshelf" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:void", "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index a8dd14d6..a38c2985 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end'; +export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'bookshelf__on_enter' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end'; diff --git a/webhooks/functions/src/typings/sdkScene.d.ts b/webhooks/functions/src/typings/sdkScene.d.ts index 298ac292..64edf2e3 100644 --- a/webhooks/functions/src/typings/sdkScene.d.ts +++ b/webhooks/functions/src/typings/sdkScene.d.ts @@ -1,4 +1,4 @@ // npm run scene-typed ; -export type TSdkScene = 'bookshelf' | 'collections' | 'home_new_user' | 'home_new_user_AccountLinking' | 'home_new_user_maybe_later' | 'home_new_user_no' | 'home_user' | 'info' | 'search'; +export type TSdkScene = 'bookshelf' | 'collections' | 'home_new_user' | 'home_new_user_AccountLinking' | 'home_new_user_maybe_later' | 'home_new_user_no' | 'home_user' | 'info' | 'search' | 'selection'; From 36356ee020502a4ddced35f8270082ad8cb469e0 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 14 Feb 2022 16:36:05 +0100 Subject: [PATCH 124/180] feat: selection second part --- sdk/custom/intents/another_one.yaml | 1 + sdk/custom/intents/en/next.yaml | 3 + sdk/custom/intents/next.yaml | 2 + sdk/custom/intents/selects_book.yaml | 12 ++ sdk/custom/scenes/selection.yaml | 33 ++++ sdk/custom/types/en/letters.yaml | 1 + sdk/custom/types/letters.yaml | 12 ++ .../src/controller/handler/selection.ts | 47 +++++ webhooks/functions/src/sdk/selection.test.ts | 162 ++++++++++++++++++ 9 files changed, 273 insertions(+) create mode 100644 sdk/custom/intents/another_one.yaml create mode 100644 sdk/custom/intents/en/next.yaml create mode 100644 sdk/custom/intents/next.yaml create mode 100644 sdk/custom/intents/selects_book.yaml create mode 100644 sdk/custom/scenes/selection.yaml create mode 100644 sdk/custom/types/en/letters.yaml create mode 100644 sdk/custom/types/letters.yaml create mode 100644 webhooks/functions/src/controller/handler/selection.ts create mode 100644 webhooks/functions/src/sdk/selection.test.ts diff --git a/sdk/custom/intents/another_one.yaml b/sdk/custom/intents/another_one.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/sdk/custom/intents/another_one.yaml @@ -0,0 +1 @@ +{} diff --git a/sdk/custom/intents/en/next.yaml b/sdk/custom/intents/en/next.yaml new file mode 100644 index 00000000..f94b1be6 --- /dev/null +++ b/sdk/custom/intents/en/next.yaml @@ -0,0 +1,3 @@ +trainingPhrases: +- another one +- next diff --git a/sdk/custom/intents/next.yaml b/sdk/custom/intents/next.yaml new file mode 100644 index 00000000..79a4e281 --- /dev/null +++ b/sdk/custom/intents/next.yaml @@ -0,0 +1,2 @@ +trainingPhrases: +- suivant diff --git a/sdk/custom/intents/selects_book.yaml b/sdk/custom/intents/selects_book.yaml new file mode 100644 index 00000000..1dbd8bad --- /dev/null +++ b/sdk/custom/intents/selects_book.yaml @@ -0,0 +1,12 @@ +parameters: +- name: letter + type: + name: letters +trainingPhrases: +- ($letter 'c' auto=false) +- ($letter 'b' auto=false) +- ($letter 'C' auto=false) +- ($letter 'B' auto=false) +- ($letter 'ah' auto=false) +- ($letter 'A' auto=false) +- ($letter 'a' auto=false) diff --git a/sdk/custom/scenes/selection.yaml b/sdk/custom/scenes/selection.yaml new file mode 100644 index 00000000..60f3e272 --- /dev/null +++ b/sdk/custom/scenes/selection.yaml @@ -0,0 +1,33 @@ +intentEvents: +- handler: + webhookHandler: selection__intent__selects_book + intent: selects_book +- handler: + webhookHandler: selection__intent__repeat + intent: repeat +- handler: + webhookHandler: selection__intent__another_one + intent: another_one +- handler: + webhookHandler: selection__intent__help + intent: help +- handler: + webhookHandler: selection__intent__fallback + intent: actions.intent.NO_MATCH_1 +- handler: + webhookHandler: selection__intent__fallback + intent: actions.intent.NO_MATCH_2 +- handler: + webhookHandler: selection__intent__fallback_end + intent: actions.intent.NO_MATCH_FINAL +- handler: + webhookHandler: selection__intent__silence + intent: actions.intent.NO_INPUT_1 +- handler: + webhookHandler: selection__intent__silence + intent: actions.intent.NO_INPUT_2 +- handler: + webhookHandler: selection__intent__silence_end + intent: actions.intent.NO_INPUT_FINAL +onEnter: + webhookHandler: selection__on_enter diff --git a/sdk/custom/types/en/letters.yaml b/sdk/custom/types/en/letters.yaml new file mode 100644 index 00000000..726911a9 --- /dev/null +++ b/sdk/custom/types/en/letters.yaml @@ -0,0 +1 @@ +synonym: {} diff --git a/sdk/custom/types/letters.yaml b/sdk/custom/types/letters.yaml new file mode 100644 index 00000000..3e495dd5 --- /dev/null +++ b/sdk/custom/types/letters.yaml @@ -0,0 +1,12 @@ +synonym: + entities: + A: + synonyms: + - A + B: + synonyms: + - B + C: + synonyms: + - C + matchType: EXACT_MATCH diff --git a/webhooks/functions/src/controller/handler/selection.ts b/webhooks/functions/src/controller/handler/selection.ts new file mode 100644 index 00000000..9078e3a7 --- /dev/null +++ b/webhooks/functions/src/controller/handler/selection.ts @@ -0,0 +1,47 @@ +import { NAME } from "../../constants"; +import { THandlerFn } from "../../type"; +import { Assistant } from "../Assistant"; +import { missing } from "./void"; + +export const selection = (app: Assistant) => { + + app.handle("selection__on_enter", enter); + app.handle("selection__intent__another_one", anotherOne); + app.handle("selection__intent__selects_book", selectBook); + app.handle("selection__intent__fallback", help); + app.handle("selection__intent__fallback_end", missing); + app.handle("selection__intent__help", help); + app.handle("selection__intent__repeat", repeat); + app.handle("selection__intent__silence", help); + app.handle("selection__intent__silence_end", missing); + +} + +const enter: THandlerFn = async (m) => { + + m.say("selection.enter.bookshelf", {number: 3}); + +} + +const selectBook: THandlerFn = async (m) => { + + m.nextScene = 'selection'; +} + +const anotherOne: THandlerFn = async (m) => { + + m.nextScene = 'selection'; +} + +const help: THandlerFn = (m) => { + + m.say("selection.help.1"); + m.say("selection.help.2"); + + m.nextScene = "selection"; +} + +const repeat: THandlerFn = (m) => { + + m.nextScene = "selection"; +} \ No newline at end of file diff --git a/webhooks/functions/src/sdk/selection.test.ts b/webhooks/functions/src/sdk/selection.test.ts new file mode 100644 index 00000000..d35c4d78 --- /dev/null +++ b/webhooks/functions/src/sdk/selection.test.ts @@ -0,0 +1,162 @@ +import {expressMocked, shell} from '../test/utils.test'; +import * as chai from 'chai'; +// import * as sinon from 'sinon'; +import {headers, body} from './conv.test'; + + +chai.should(); + +const scene = 'selection'; + +const yaml = `intentEvents: +- handler: + webhookHandler: selection__intent__selects_book + intent: selects_book +- handler: + webhookHandler: selection__intent__repeat + intent: repeat +- handler: + webhookHandler: selection__intent__another_one + intent: another_one +- handler: + webhookHandler: selection__intent__help + intent: help +- handler: + webhookHandler: selection__intent__fallback + intent: actions.intent.NO_MATCH_1 +- handler: + webhookHandler: selection__intent__fallback + intent: actions.intent.NO_MATCH_2 +- handler: + webhookHandler: selection__intent__fallback_end + intent: actions.intent.NO_MATCH_FINAL +- handler: + webhookHandler: selection__intent__silence + intent: actions.intent.NO_INPUT_1 +- handler: + webhookHandler: selection__intent__silence + intent: actions.intent.NO_INPUT_2 +- handler: + webhookHandler: selection__intent__silence_end + intent: actions.intent.NO_INPUT_FINAL +onEnter: + webhookHandler: selection__on_enter +`; + +describe(scene + ' handler', () => { + describe('sdk', () => { + it('check main scene', (done) => { + shell(`cat custom/scenes/${scene}.yaml`, (stdout) => { + stdout.should.to.be.eq(yaml); + }, done); + }); + }); + + describe('app', () => { + it('on enter', async () => { + body.handler.name = 'selection__on_enter'; + body.scene.name = scene; + + const message = `Here are the first 3 titles on your bookshelf:\n`; + + // TODO + // LOT of Code here because all messages will be in on-enter + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + }); + + it('select book', async () => { + body.handler.name = 'selection__intent__selects_book'; + body.scene.name = scene; + + // TODO check type validation + + const data = await expressMocked(body, headers); + + data.scene.next.name.should.to.be.eq('selection'); + // or + // say the fallback message if type is incorrect + // need to check with google data + }); + + it('another one', async () => { + body.handler.name = 'selection__intent__another_one'; + body.scene.name = scene; + + // TODO check session data page incr + + const data = await expressMocked(body, headers); + + data.scene.next.name.should.to.be.eq('selection'); + }); + + it('repeat', async () => { + body.handler.name = 'selection__intent__repeat'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.scene.next.name.should.to.be.eq('selection'); + }); + + const help = `Pick one out of 3 titles by mentioning their letter, A - B or C, or ask for their summary by saying 'Summary of A'. You can also ask for 'another one' or directly search by genre, author or book title.\nWhat would you like to do?\n`; + + it('help', async () => { + body.handler.name = 'selection__intent__help'; + body.scene.name = scene; + + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('selection'); + }); + + it('fallback 1 and 2', async () => { + body.handler.name = 'selection__intent__fallback'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('selection'); + }); + + it('fallback 3', async () => { + body.handler.name = 'selection__intent__fallback_end'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + + // data.scene.next.name.should.to.be.eq('home_new_user'); + }); + + it('silence 1 and 2', async () => { + body.handler.name = 'selection__intent__silence'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('selection'); + }); + + it('silence 3', async () => { + body.handler.name = 'selection__intent__silence_end'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + + // data.scene.next.name.should.to.be.eq('home_new_user'); + }); + }); +}); From 39d579d3d135422ccf82e0081033b1e49a237314 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 14 Feb 2022 19:54:28 +0100 Subject: [PATCH 125/180] fix: storageModel singleton --- webhooks/functions/src/model/storage.model.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/webhooks/functions/src/model/storage.model.ts b/webhooks/functions/src/model/storage.model.ts index d366002a..554d7606 100644 --- a/webhooks/functions/src/model/storage.model.ts +++ b/webhooks/functions/src/model/storage.model.ts @@ -2,23 +2,18 @@ import {ok} from 'assert'; import {pull, push} from './database'; import {StorageDto} from './storage.dto'; +let storageModel: StorageModel | undefined; + export class StorageModel { private _bearer: string; private _storage: StorageDto; - private static _singleton: boolean; constructor(bearerToken: string, store: StorageDto) { - if (StorageModel._singleton) { - throw new Error('already instancied'); - } - ok(bearerToken); this._bearer = bearerToken; ok(store instanceof StorageDto); this._storage = store; - - StorageModel._singleton = true; } public static async create(bearerToken: string) { @@ -27,7 +22,12 @@ export class StorageModel { const store = StorageDto.create(bearerToken, data); // let's to cascading the storage errors accross storage -> storageModel -> Machine -> Assistant - return new StorageModel(bearerToken, store); + if (storageModel) { + console.info('storageModel already instancied'); + return storageModel; + } + storageModel = new StorageModel(bearerToken, store); + return storageModel; } public async save() { From d22de54260082c337f296a2da7813fe0b695ac1d Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 14 Feb 2022 20:12:01 +0100 Subject: [PATCH 126/180] fix: global cancel, fallback and silence --- sdk/custom/global/actions.intent.CANCEL.yaml | 2 +- .../global/actions.intent.NO_INPUT_1.yaml | 3 +- .../global/actions.intent.NO_INPUT_2.yaml | 3 +- .../global/actions.intent.NO_INPUT_FINAL.yaml | 2 ++ .../global/actions.intent.NO_MATCH_1.yaml | 3 +- .../global/actions.intent.NO_MATCH_2.yaml | 3 +- .../global/actions.intent.NO_MATCH_FINAL.yaml | 2 ++ ...tic_prompt_2.yaml => static_prompt_1.yaml} | 0 ...tic_prompt_2.yaml => static_prompt_1.yaml} | 0 sdk/settings/settings.yaml | 8 ++++++ sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 6 ++++ .../functions/src/controller/handler/index.ts | 28 ++++++++++++++++++- webhooks/functions/src/translation/en/en.json | 13 ++++++++- webhooks/functions/src/typings/i18n.d.ts | 4 +-- .../functions/src/typings/sdkHandler.d.ts | 2 +- 15 files changed, 69 insertions(+), 10 deletions(-) rename sdk/custom/prompts/en/{static_prompt_2.yaml => static_prompt_1.yaml} (100%) rename sdk/custom/prompts/{static_prompt_2.yaml => static_prompt_1.yaml} (100%) diff --git a/sdk/custom/global/actions.intent.CANCEL.yaml b/sdk/custom/global/actions.intent.CANCEL.yaml index 1a60bac3..4ff4d263 100644 --- a/sdk/custom/global/actions.intent.CANCEL.yaml +++ b/sdk/custom/global/actions.intent.CANCEL.yaml @@ -1,4 +1,4 @@ handler: - staticPromptName: static_prompt_2 + staticPromptName: static_prompt_1 webhookHandler: cancel transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/custom/global/actions.intent.NO_INPUT_1.yaml b/sdk/custom/global/actions.intent.NO_INPUT_1.yaml index 0967ef42..a92bb198 100644 --- a/sdk/custom/global/actions.intent.NO_INPUT_1.yaml +++ b/sdk/custom/global/actions.intent.NO_INPUT_1.yaml @@ -1 +1,2 @@ -{} +handler: + webhookHandler: silence_1 diff --git a/sdk/custom/global/actions.intent.NO_INPUT_2.yaml b/sdk/custom/global/actions.intent.NO_INPUT_2.yaml index 0967ef42..3cb1a45c 100644 --- a/sdk/custom/global/actions.intent.NO_INPUT_2.yaml +++ b/sdk/custom/global/actions.intent.NO_INPUT_2.yaml @@ -1 +1,2 @@ -{} +handler: + webhookHandler: silence_2 diff --git a/sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml b/sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml index af0c87f2..f4869858 100644 --- a/sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml +++ b/sdk/custom/global/actions.intent.NO_INPUT_FINAL.yaml @@ -1 +1,3 @@ +handler: + webhookHandler: silence_end transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/custom/global/actions.intent.NO_MATCH_1.yaml b/sdk/custom/global/actions.intent.NO_MATCH_1.yaml index 0967ef42..59af8936 100644 --- a/sdk/custom/global/actions.intent.NO_MATCH_1.yaml +++ b/sdk/custom/global/actions.intent.NO_MATCH_1.yaml @@ -1 +1,2 @@ -{} +handler: + webhookHandler: fallback_1 diff --git a/sdk/custom/global/actions.intent.NO_MATCH_2.yaml b/sdk/custom/global/actions.intent.NO_MATCH_2.yaml index 0967ef42..c5df3091 100644 --- a/sdk/custom/global/actions.intent.NO_MATCH_2.yaml +++ b/sdk/custom/global/actions.intent.NO_MATCH_2.yaml @@ -1 +1,2 @@ -{} +handler: + webhookHandler: fallback_2 diff --git a/sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml b/sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml index af0c87f2..c72b085b 100644 --- a/sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml +++ b/sdk/custom/global/actions.intent.NO_MATCH_FINAL.yaml @@ -1 +1,3 @@ +handler: + webhookHandler: fallback_end transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/custom/prompts/en/static_prompt_2.yaml b/sdk/custom/prompts/en/static_prompt_1.yaml similarity index 100% rename from sdk/custom/prompts/en/static_prompt_2.yaml rename to sdk/custom/prompts/en/static_prompt_1.yaml diff --git a/sdk/custom/prompts/static_prompt_2.yaml b/sdk/custom/prompts/static_prompt_1.yaml similarity index 100% rename from sdk/custom/prompts/static_prompt_2.yaml rename to sdk/custom/prompts/static_prompt_1.yaml diff --git a/sdk/settings/settings.yaml b/sdk/settings/settings.yaml index f71553da..78d52f80 100644 --- a/sdk/settings/settings.yaml +++ b/sdk/settings/settings.yaml @@ -1,3 +1,8 @@ +accountLinking: + appClientId: "123456" + authGrantType: IMPLICIT + authorizationUrl: https://opds-auth-test-server-aplqpqv3wa-ey.a.run.app/implicit + linkingType: OAUTH category: EDUCATION_AND_REFERENCE defaultLocale: fr localizedSettings: @@ -5,3 +10,6 @@ localizedSettings: pronunciation: edrlab voice: female_1 projectId: edrlab-1 +testingInstructions: |- + admin + admin diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index 4f5807a7..f5efb886 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -58,6 +58,12 @@ handlers: - name: selection__intent__fallback_end - name: selection__intent__silence - name: selection__intent__silence_end +- name: fallback_1 +- name: fallback_2 +- name: fallback_end +- name: silence_1 +- name: silence_2 +- name: silence_end httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/controller/handler/index.ts b/webhooks/functions/src/controller/handler/index.ts index 41d834b4..e095d48b 100644 --- a/webhooks/functions/src/controller/handler/index.ts +++ b/webhooks/functions/src/controller/handler/index.ts @@ -11,7 +11,33 @@ export const handler = (app = new Assistant({})) => { app.handle('main', main); - app.handle('cancel', () => {}); + app.handle('cancel', (m) => { + m.say('bye.1'); + }); + + app.handle('fallback_1', (m) => { + m.say('fallback.1'); + }); + + app.handle('fallback_2', (m) => { + m.say('fallback.2'); + }); + + app.handle('fallback_end', (m) => { + m.say('bye.1'); + }); + + app.handle('silence_1', (m) => { + m.say('silence.1'); + }); + + app.handle('silence_2', (m) => { + m.say('silence.2'); + }); + + app.handle('silence_end', (m) => { + m.say('bye.1'); + }); home_user(app); home_new_user(app); diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index 0b0a11c3..d443dfa4 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -92,5 +92,16 @@ "2": "What would you like to do?" } }, - "void": "need to replace this message" + "void": "need to replace this message", + "bye": { + "1": "Thank you for trying the app. To pick up your reading again, come back any time" + }, + "fallback": { + "1": "I did not understand", + "2": "I really did not understand" + }, + "silence": { + "1": "I did not hear", + "2": "I really did not hear" + } } \ No newline at end of file diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index c8fade92..bae64390 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "selection.enter.bookshelf" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "void", + "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "selection.enter.bookshelf" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2", "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:selection.enter.bookshelf" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:void", + "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:selection.enter.bookshelf" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2", "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index a38c2985..b453a8fd 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'bookshelf__on_enter' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end'; +export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'bookshelf__on_enter' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end'; From a6a92f81010111020f3001f6223ee4d8ed0c46c9 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 14 Feb 2022 20:14:19 +0100 Subject: [PATCH 127/180] fix: gactions cancel --- sdk/custom/global/actions.intent.CANCEL.yaml | 1 - sdk/custom/prompts/en/static_prompt_1.yaml | 6 ------ sdk/custom/prompts/static_prompt_1.yaml | 5 ----- 3 files changed, 12 deletions(-) delete mode 100644 sdk/custom/prompts/en/static_prompt_1.yaml delete mode 100644 sdk/custom/prompts/static_prompt_1.yaml diff --git a/sdk/custom/global/actions.intent.CANCEL.yaml b/sdk/custom/global/actions.intent.CANCEL.yaml index 4ff4d263..1166ed64 100644 --- a/sdk/custom/global/actions.intent.CANCEL.yaml +++ b/sdk/custom/global/actions.intent.CANCEL.yaml @@ -1,4 +1,3 @@ handler: - staticPromptName: static_prompt_1 webhookHandler: cancel transitionToScene: actions.scene.END_CONVERSATION diff --git a/sdk/custom/prompts/en/static_prompt_1.yaml b/sdk/custom/prompts/en/static_prompt_1.yaml deleted file mode 100644 index 9aec5f68..00000000 --- a/sdk/custom/prompts/en/static_prompt_1.yaml +++ /dev/null @@ -1,6 +0,0 @@ -candidates: -- promptResponse: - firstSimple: - variants: - - speech: Thank you for trying the app. To pick up your reading again, come - back any time diff --git a/sdk/custom/prompts/static_prompt_1.yaml b/sdk/custom/prompts/static_prompt_1.yaml deleted file mode 100644 index 38ae8904..00000000 --- a/sdk/custom/prompts/static_prompt_1.yaml +++ /dev/null @@ -1,5 +0,0 @@ -candidates: -- promptResponse: - firstSimple: - variants: - - speech: merci au revoir From fa43edd508f57d9786b60baa9261970577505ed6 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 14 Feb 2022 20:14:30 +0100 Subject: [PATCH 128/180] fix: authorization url --- sdk/settings/settings.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/settings/settings.yaml b/sdk/settings/settings.yaml index 78d52f80..bc7bc07e 100644 --- a/sdk/settings/settings.yaml +++ b/sdk/settings/settings.yaml @@ -1,7 +1,7 @@ accountLinking: appClientId: "123456" authGrantType: IMPLICIT - authorizationUrl: https://opds-auth-test-server-aplqpqv3wa-ey.a.run.app/implicit + authorizationUrl: https://opds-auth-test-server-aplqpqv3wa-ey.a.run.app/implicit/login linkingType: OAUTH category: EDUCATION_AND_REFERENCE defaultLocale: fr From 64f43bf1980d90c3571f7ad49737c0590a691a07 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 14 Feb 2022 20:24:40 +0100 Subject: [PATCH 129/180] feat: switch select-book with numbers instead of letters --- .../intents/en/{next.yaml => another_one.yaml} | 4 +++- sdk/custom/intents/en/selects_book.yaml | 11 +++++++++++ sdk/custom/intents/next.yaml | 2 -- sdk/custom/intents/selects_book.yaml | 4 ++-- sdk/custom/types/en/letters.yaml | 1 - sdk/custom/types/letters.yaml | 12 ------------ 6 files changed, 16 insertions(+), 18 deletions(-) rename sdk/custom/intents/en/{next.yaml => another_one.yaml} (58%) create mode 100644 sdk/custom/intents/en/selects_book.yaml delete mode 100644 sdk/custom/intents/next.yaml delete mode 100644 sdk/custom/types/en/letters.yaml delete mode 100644 sdk/custom/types/letters.yaml diff --git a/sdk/custom/intents/en/next.yaml b/sdk/custom/intents/en/another_one.yaml similarity index 58% rename from sdk/custom/intents/en/next.yaml rename to sdk/custom/intents/en/another_one.yaml index f94b1be6..790fb96e 100644 --- a/sdk/custom/intents/en/next.yaml +++ b/sdk/custom/intents/en/another_one.yaml @@ -1,3 +1,5 @@ trainingPhrases: -- another one +- the next one - next +- next page +- another one diff --git a/sdk/custom/intents/en/selects_book.yaml b/sdk/custom/intents/en/selects_book.yaml new file mode 100644 index 00000000..bc26304d --- /dev/null +++ b/sdk/custom/intents/en/selects_book.yaml @@ -0,0 +1,11 @@ +trainingPhrases: +- the ($number 'first' auto=false) +- the ($number 'second' auto=false) +- the ($number 'third' auto=false) +- the number ($number 'one' auto=false) +- the number ($number 'three' auto=true) +- ($number 'three' auto=true) +- ($number 'two' auto=true) +- ($number 'one' auto=false) +- the ($number 'two' auto=true) +- the ($number 'one' auto=false) diff --git a/sdk/custom/intents/next.yaml b/sdk/custom/intents/next.yaml deleted file mode 100644 index 79a4e281..00000000 --- a/sdk/custom/intents/next.yaml +++ /dev/null @@ -1,2 +0,0 @@ -trainingPhrases: -- suivant diff --git a/sdk/custom/intents/selects_book.yaml b/sdk/custom/intents/selects_book.yaml index 1dbd8bad..59df0111 100644 --- a/sdk/custom/intents/selects_book.yaml +++ b/sdk/custom/intents/selects_book.yaml @@ -1,7 +1,7 @@ parameters: -- name: letter +- name: number type: - name: letters + name: actions.type.Number trainingPhrases: - ($letter 'c' auto=false) - ($letter 'b' auto=false) diff --git a/sdk/custom/types/en/letters.yaml b/sdk/custom/types/en/letters.yaml deleted file mode 100644 index 726911a9..00000000 --- a/sdk/custom/types/en/letters.yaml +++ /dev/null @@ -1 +0,0 @@ -synonym: {} diff --git a/sdk/custom/types/letters.yaml b/sdk/custom/types/letters.yaml deleted file mode 100644 index 3e495dd5..00000000 --- a/sdk/custom/types/letters.yaml +++ /dev/null @@ -1,12 +0,0 @@ -synonym: - entities: - A: - synonyms: - - A - B: - synonyms: - - B - C: - synonyms: - - C - matchType: EXACT_MATCH From 1e5baa19ef563e13688784a359814abf0a81b98b Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 15 Feb 2022 15:16:49 +0100 Subject: [PATCH 130/180] feat: selection test part one --- webhooks/functions/src/controller/Machine.ts | 2 + .../controller/handler/selection.helper.ts | 19 ++ .../functions/src/model/data.model.test.ts | 15 + webhooks/functions/src/model/storage.dto.ts | 2 + .../functions/src/model/storage.interface.ts | 11 + webhooks/functions/src/model/storage.test.ts | 23 +- webhooks/functions/src/sdk/selection.test.ts | 308 +++++++++++++++++- webhooks/functions/src/test/utils.test.ts | 7 +- webhooks/functions/src/translation/en/en.json | 23 +- webhooks/functions/src/typings/i18n.d.ts | 4 +- 10 files changed, 375 insertions(+), 39 deletions(-) create mode 100644 webhooks/functions/src/controller/handler/selection.helper.ts diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 0b3b6acb..72bbb577 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -5,6 +5,7 @@ import {TKeySessionScene, TStateAuthentication} from '../model/storage.interface import {StorageModel} from '../model/storage.model'; import {i18n, TI18n, TI18nKey} from '../translation'; import {IConversationV3, TSdkScene2} from '../type'; +import {resetSelection} from './handler/selection.helper'; export class Machine { private _conv: IConversationV3; @@ -174,6 +175,7 @@ export class Machine { 'home_user': { state: 'DEFAULT', }, + 'selection': resetSelection(), }, }; this._model.store.user.sessionId = id; diff --git a/webhooks/functions/src/controller/handler/selection.helper.ts b/webhooks/functions/src/controller/handler/selection.helper.ts new file mode 100644 index 00000000..8a280c8f --- /dev/null +++ b/webhooks/functions/src/controller/handler/selection.helper.ts @@ -0,0 +1,19 @@ +import { IStorageSession } from "../../model/storage.interface"; + +export const resetSelection = (): IStorageSession["scene"]["selection"] => ({ + from: 'main', + kind: 'GROUP', + nextUrlCounter: 0, + state: "DEFAULT", + url: "", + nbChoice: 0, +}); +export const resetSessionsSelection = (session: IStorageSession) => { + + session.scene.selection.from = 'main'; + session.scene.selection.kind = 'GROUP'; + session.scene.selection.nextUrlCounter = 0; + session.scene.selection.state = "DEFAULT"; + session.scene.selection.url = ""; + session.scene.selection.nbChoice = 0; +} \ No newline at end of file diff --git a/webhooks/functions/src/model/data.model.test.ts b/webhooks/functions/src/model/data.model.test.ts index f9258425..3c0e6b91 100644 --- a/webhooks/functions/src/model/data.model.test.ts +++ b/webhooks/functions/src/model/data.model.test.ts @@ -16,6 +16,13 @@ export const freshDataClone = () => Object.assign({ home_user: { state: 'DEFAULT', }, + selection: { + state: 'DEFAULT', + kind: 'GROUP', + url: '', + nextUrlCounter: 0, + from: 'main', + }, }, }, user: { @@ -36,6 +43,14 @@ export const parsedDataClone = (): IStorage => ({ home_user: { state: 'DEFAULT', }, + selection: { + state: 'DEFAULT', + kind: 'GROUP', + url: '', + nextUrlCounter: 0, + from: 'main', + nbChoice: 0, + }, }, }, user: { diff --git a/webhooks/functions/src/model/storage.dto.ts b/webhooks/functions/src/model/storage.dto.ts index 5d18f457..8a1fe407 100644 --- a/webhooks/functions/src/model/storage.dto.ts +++ b/webhooks/functions/src/model/storage.dto.ts @@ -2,6 +2,7 @@ import * as util from 'util'; import {ISessionScene, IStorage, IStoragePlayer, IStoragePlayerCurrent, IStoragePlayerHistory, IStorageSession, IStorageUser, TStateAuthentication} from './storage.interface'; import {classToPlain, Exclude, plainToClass, Transform, TransformationType, Type} from 'class-transformer'; import {Equals, IsBoolean, IsDate, IsNotEmpty, IsNumber, IsObject, IsOptional, IsString, IsUrl, Min, ValidateNested, validateSync} from 'class-validator'; +import {resetSelection} from '../controller/handler/selection.helper'; const DB_VERSION = 1; @@ -93,6 +94,7 @@ class StorageSessionDto implements IStorageSession { 'home_user': { state: 'DEFAULT', }, + 'selection': resetSelection(), }; } } diff --git a/webhooks/functions/src/model/storage.interface.ts b/webhooks/functions/src/model/storage.interface.ts index dcb9c3a1..c2554c28 100644 --- a/webhooks/functions/src/model/storage.interface.ts +++ b/webhooks/functions/src/model/storage.interface.ts @@ -1,3 +1,4 @@ +import {TSdkHandler} from '../typings/sdkHandler'; export interface IStoragePlayerHistory { index: number; @@ -20,10 +21,20 @@ export interface IStoragePlayer { export type TStateDefault = 'DEFAULT' export type TStateAuthentication = 'NO_LINKED' | 'NEWLY_LINKED' | 'LINKED' | TStateDefault; export type TStateHomeUser = 'SESSION' | TStateDefault; +export type TStateSelection = 'RUNNING' | 'FINISH' | TStateDefault; +export type TKindSelection = 'PUBLICATION' | 'GROUP'; export interface ISessionScene { 'home_user': { state: TStateHomeUser, + }, + 'selection': { + state: TStateSelection, + kind: TKindSelection, + url: string, + nextUrlCounter: number, + from: TSdkHandler, + nbChoice: number, } } export type TKeySessionScene = keyof ISessionScene; diff --git a/webhooks/functions/src/model/storage.test.ts b/webhooks/functions/src/model/storage.test.ts index 34ecbafd..814f85d7 100644 --- a/webhooks/functions/src/model/storage.test.ts +++ b/webhooks/functions/src/model/storage.test.ts @@ -147,28 +147,7 @@ describe('storage Model', () => { chai.should(); beforeEach(() => { - freshData = { - dbVersion: 1, - bearerToken: 'test', - player: { - current: { - playing: false, - }, - history: { - - }, - }, - session: { - scene: { - home_user: { - state: 'DEFAULT', - }, - }, - }, - user: { - authentication: 'NO_LINKED', - }, - }; + freshData = freshDataClone(); }); // @ts-ignore diff --git a/webhooks/functions/src/sdk/selection.test.ts b/webhooks/functions/src/sdk/selection.test.ts index d35c4d78..76400f86 100644 --- a/webhooks/functions/src/sdk/selection.test.ts +++ b/webhooks/functions/src/sdk/selection.test.ts @@ -1,7 +1,9 @@ -import {expressMocked, shell} from '../test/utils.test'; +import {expressMocked, shell, storageModelMocked} from '../test/utils.test'; import * as chai from 'chai'; // import * as sinon from 'sinon'; import {headers, body} from './conv.test'; +import {parsedDataClone} from '../model/data.model.test'; +import {IOpdsResultView} from 'opds-fetcher-parser/build/src/interface/opds'; chai.should(); @@ -52,30 +54,320 @@ describe(scene + ' handler', () => { }); }); + const messageHelpers = (number: number, it: Array<[nb: number, title: string]>) => { + const a = 'Pick one of these by saying their numbers.\n'; + const b = it.reduce((pv, [nb, title]) => `${nb}. ${title}\n`, ''); + const c = 'Which one would you like to start reading? Or perhaps you\'d like to explore the other titles on your bookshelf?\n'; + return a + b + c; + }; + describe('app', () => { it('on enter', async () => { body.handler.name = 'selection__on_enter'; body.scene.name = scene; - const message = `Here are the first 3 titles on your bookshelf:\n`; // TODO // LOT of Code here because all messages will be in on-enter - const data = await expressMocked(body, headers); + // test si state === "running" sinon forward vers la bonne scene + // tant que state !=== 'finish' dire à l'utilisateur les resultats + // soit de groupes ou soit de publications puis demander le numéro + // lorsque le numéro est vérifier dans select book intent + // vérifier le numéro dans la state machine et afficher la proposition + // lorsque cela est la derniere page afficher la page en cours et dire un message + // + // ici ce trouve la machine a état de selection + // nécéssite surement d'étoffer les états .. au lieu de les morcelés + + // state === running + // 1) check url + // 2) check page + // 3) if (last page) ->say + // 4) afficher resultat + + // state === finish + // 1) check url + // 2) check page ((else an error happen (reset ? ))) + // 3) routing table with from handler + + // 1) state === running + // 2) vérifier url + // 3) vérifier page + // 4) afficher utilisateur + // 5) attendre numéro + // 6) checker ce numéro + // 7) afficher utilisateur + // 8) attendre num + // 9) check num + // 10) last page -> say user + // 11) afficher user + // 12) good choice user + // 13) machine finish + // 15) table de routage prochaine scene en fonction de sceneFrom + + const message = `Oops, something went wrong. I will send you back to the home menu\n`; + + const pullData = parsedDataClone(); + const data = await expressMocked(body, headers, pullData); data.prompt.firstSimple.speech.should.to.be.eq(message); + + // must redirect to home_user when the state machine not initialized + data.scene.next.name.should.to.be.eq('home_user'); }); - it('select book', async () => { - body.handler.name = 'selection__intent__selects_book'; + it('on enter - state running - no url', async () => { + body.handler.name = 'selection__on_enter'; body.scene.name = scene; - // TODO check type validation + const pullData = parsedDataClone(); + pullData.session.scene.selection.state = 'RUNNING'; + const data = await expressMocked(body, headers, pullData); - const data = await expressMocked(body, headers); + const message = `Oops, something went wrong. I will send you back to the home menu\n`; + data.prompt.firstSimple.speech.should.to.be.eq(message); + data.scene.next.name.should.to.be.eq('home_user'); + }); + + const testStateRunningPublication = () => { + const pullData = parsedDataClone(); + pullData.session.scene.selection.state = 'RUNNING'; + pullData.session.scene.selection.url = 'http://my.url'; + pullData.session.scene.selection.kind = 'PUBLICATION'; + + const feed: Partial = { + publications: [ + { + title: 'first publication', + baseUrl: '', + authors: [], + numberOfPages: 0, + }, + { + title: 'second publication', + baseUrl: '', + authors: [], + numberOfPages: 0, + }, + { + title: 'third publication', + baseUrl: '', + authors: [], + numberOfPages: 0, + }, + ], + }; + const message = messageHelpers(3, [ + [1, 'first publication'], + [2, 'second publication'], + [3, 'third publication'], + ]); + + return {pullData, feed, message}; + }; + const testStateRunningGroup = () => { + const pullData = parsedDataClone(); + pullData.session.scene.selection.state = 'RUNNING'; + pullData.session.scene.selection.url = 'http://my.url'; + pullData.session.scene.selection.kind = 'GROUP'; + + const feed: Partial = { + publications: [ + { + title: 'first group', + baseUrl: '', + authors: [], + numberOfPages: 0, + }, + { + title: 'second group', + baseUrl: '', + authors: [], + numberOfPages: 0, + }, + { + title: 'third group', + baseUrl: '', + authors: [], + numberOfPages: 0, + }, + ], + }; + const message = messageHelpers(3, [ + [1, 'first group'], + [2, 'second group'], + [3, 'third group'], + ]); + + return {pullData, feed, message}; + }; + + it('on enter - state running - publication list first page with no next link', async () => { + body.handler.name = 'selection__on_enter'; + body.scene.name = scene; + + const {pullData, feed, message} = testStateRunningPublication(); + pullData.session.scene.selection.nextUrlCounter = 0; + + // @ts-ignore + feed.links = {}; + + const data = await expressMocked(body, headers, pullData, feed); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + data.scene.next.name.should.to.be.eq('selection'); + }); + it('on enter - state running - group list first page with no next link', async () => { + body.handler.name = 'selection__on_enter'; + body.scene.name = scene; + + const {pullData, feed, message} = testStateRunningGroup(); + const data = await expressMocked(body, headers, pullData, feed); + // @ts-ignore + feed.links = {}; + + // must say the first page + data.prompt.firstSimple.speech.should.to.be.eq(message); + data.scene.next.name.should.to.be.eq('selection'); + }); + + it('on enter - state running - publication list last page', async () => { + body.handler.name = 'selection__on_enter'; + body.scene.name = scene; + + const {pullData, feed, message} = testStateRunningPublication(); + pullData.session.scene.selection.nextUrlCounter = 3; + // @ts-ignore + feed.links = {}; + const data = await expressMocked(body, headers, pullData, feed); + + data.prompt.firstSimple.speech.should.to.be.eq('Here\'s the last available books\n' + message); data.scene.next.name.should.to.be.eq('selection'); + }); + + it('on enter - state running - group list last page', async () => { + body.handler.name = 'selection__on_enter'; + body.scene.name = scene; + + const {pullData, feed, message} = testStateRunningGroup(); + pullData.session.scene.selection.nextUrlCounter = 3; + // @ts-ignore + feed.links = {}; + const data = await expressMocked(body, headers, pullData, feed); + + // must say the first page + data.prompt.firstSimple.speech.should.to.be.eq('Here\'s the last available groups\n' + message); + data.scene.next.name.should.to.be.eq('selection'); + }); + + it('on enter - state running - publication list page > 0', async () => { + body.handler.name = 'selection__on_enter'; + body.scene.name = scene; + + const {pullData, feed, message} = testStateRunningPublication(); + pullData.session.scene.selection.nextUrlCounter = 3; + // @ts-ignore + feed.links = { + next: [ + { + url: 'http://my.url', + }, + ], + }; + const data = await expressMocked(body, headers, pullData, feed); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + data.scene.next.name.should.to.be.eq('selection'); + }); + + it('on enter - state running - group list last page > 0', async () => { + body.handler.name = 'selection__on_enter'; + body.scene.name = scene; + + const {pullData, feed, message} = testStateRunningGroup(); + pullData.session.scene.selection.nextUrlCounter = 3; + // @ts-ignore + feed.links = { + next: [ + { + url: 'http://my.url', + }, + ], + }; + const data = await expressMocked(body, headers, pullData, feed); + + // must say the first page + data.prompt.firstSimple.speech.should.to.be.eq(message); + data.scene.next.name.should.to.be.eq('selection'); + }); + + it('on enter - state running - publication list with next page - from bookshelf', async () => { + body.handler.name = 'selection__on_enter'; + body.scene.name = scene; + + const {pullData, feed, message} = testStateRunningPublication(); + pullData.session.scene.selection.nextUrlCounter = 0; + pullData.session.scene.selection.from = 'home_user__intent__bookshelf', + // @ts-ignore + feed.links = { + next: [ + { + url: 'http://my.url', + }, + ], + }; + const data = await expressMocked(body, headers, pullData, feed); + + const message2 = 'Here are the first 3 titles on your bookshelf:\n' + message + 'Or perhaps you\'d like to explore the other titles on your bookshelf?\n'; + + data.prompt.firstSimple.speech.should.to.be.eq(message2); + data.scene.next.name.should.to.be.eq('selection'); + }); + + // @TODO + // complete the test from handler + // it('on enter - state running - group list last with next page - from collection', async () => { + + // body.handler.name = 'selection__on_enter'; + // body.scene.name = scene; + + // const {pullData, feed, message} = testStateRunningGroup(); + // pullData.session.scene.selection.nextUrlCounter = 3; + // // @ts-ignore + // feed.links = { + // next: [ + // { + // url: "http://my.url" + // } + // ] + // }; + // const data = await expressMocked(body, headers, pullData, feed); + + // // must say the first page + // data.prompt.firstSimple.speech.should.to.be.eq(message); + // data.scene.next.name.should.to.be.eq('selection'); + + // }); + + it('select book - number 1', async () => { + body.handler.name = 'selection__intent__selects_book'; + body.scene.name = scene; + body.intent.params = { + number: { + original: '1', + resolved: 1, + }, + }; + + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + const data = await expressMocked(body, headers, undefined, undefined, undefined, model); + + data.scene.next.name.should.to.be.eq('selection'); + model.data.store.session.scene.selection.state.should.to.be.eq('FINISH'); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(1); // or // say the fallback message if type is incorrect // need to check with google data @@ -85,8 +377,6 @@ describe(scene + ' handler', () => { body.handler.name = 'selection__intent__another_one'; body.scene.name = scene; - // TODO check session data page incr - const data = await expressMocked(body, headers); data.scene.next.name.should.to.be.eq('selection'); diff --git a/webhooks/functions/src/test/utils.test.ts b/webhooks/functions/src/test/utils.test.ts index 6de162f1..00d8f7e3 100644 --- a/webhooks/functions/src/test/utils.test.ts +++ b/webhooks/functions/src/test/utils.test.ts @@ -14,6 +14,7 @@ import * as httpMocks from 'node-mocks-http'; import {IStorage} from '../model/storage.interface'; import {OpdsFetcher} from 'opds-fetcher-parser'; import {IWebPubView} from 'opds-fetcher-parser/build/src/interface/webpub'; +import {IOpdsResultView} from 'opds-fetcher-parser/build/src/interface/opds'; export const defaults = { cwd: process.env.PWD + '/' + SDK_PATH, @@ -60,8 +61,10 @@ export const fetcherMocked = (feed?: any, webpub?: Partial) => { return fetcher; }; -export const expressMocked = async (body: JsonObject, headers: JsonObject, pullData: IStorage | undefined = undefined, feed: any | undefined = undefined, webpub: Partial | undefined = undefined) => { - const {data /* , push, pull*/} = await storageModelMocked(pullData); +export const expressMocked = async (body: JsonObject, headers: JsonObject, pullData: IStorage | undefined = undefined, feed: Partial | undefined = undefined, webpub: Partial | undefined = undefined, data: any = undefined) => { + if (!data) { + ({data /* , push, pull*/} = await storageModelMocked(pullData)); + } const fetcher = fetcherMocked(feed, webpub) as unknown as OpdsFetcher; const assistant = new Assistant({storageModel: data, fetcher}); diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index d443dfa4..e091b752 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -77,11 +77,23 @@ }, "selection": { "enter": { - "bookshelf": "Here are the first {{- number}} titles on your bookshelf:", + "bookshelf": { + "first": "Here are the first {{- number}} titles on your bookshelf:", + "second": "Or perhaps you'd like to explore the other titles on your bookshelf?" + }, + "search": "I found {{- number}} books with that title", + "collection": { + "publication": "I found {{- number}} books", + "group": "I found {{- number}} groups" + }, + "lastPage": { + "publication": "Here's the last available books", + "group": "Here's the last available groups" + }, "common": { - "1": "Pick one of these books by saying their letter, or ask for their summary by saying 'Summary of A', for example.", - "2": "{{- letter}}. {{- title}}", - "3": "Which one would you like to start reading? Or perhaps you'd like to explore the other titles on your bookshelf?" + "1": "Pick one of these by saying their numbers.", + "2": "{{- symbol}}. {{- title}}", + "3": "Which one would you like to start reading?" }, "empty": { "1": "Uh Oh! Nothing to read here quite yet. Not to worry though, we can fix that right away! Would you like to browse our collections? Or perhaps you'd like to search for a specific book by author or book title?" @@ -103,5 +115,8 @@ "silence": { "1": "I did not hear", "2": "I really did not hear" + }, + "error": { + "1": "Oops, something went wrong. I will send you back to the home menu" } } \ No newline at end of file diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index bae64390..ba1756b4 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "selection.enter.bookshelf" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2", + "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:selection.enter.bookshelf" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2", + "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } From 180b35f78dda1947094a48afb7a7e47df057d949 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 15 Feb 2022 16:15:53 +0100 Subject: [PATCH 131/180] feat: test selection part two --- webhooks/functions/src/controller/Machine.ts | 6 +- .../src/controller/handler/selection.ts | 2 - .../functions/src/model/data.model.test.ts | 5 +- webhooks/functions/src/sdk/selection.test.ts | 100 ++++++++++++++++-- webhooks/functions/src/test/utils.test.ts | 2 +- webhooks/functions/src/translation/en/en.json | 3 +- webhooks/functions/src/typings/i18n.d.ts | 4 +- 7 files changed, 105 insertions(+), 17 deletions(-) diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 72bbb577..eee2ee69 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -165,7 +165,11 @@ export class Machine { if (!id) { return; } - const sameSession = id === this._model.store.user.sessionId; + const idFromStore = this._model.store.user.sessionId; + if (!idFromStore) { + console.info('no user session id saved in database'); + } + const sameSession = id === idFromStore; if (sameSession) { console.info('MIDDLEWARE :: Session in progress'); } else { diff --git a/webhooks/functions/src/controller/handler/selection.ts b/webhooks/functions/src/controller/handler/selection.ts index 9078e3a7..9424e7b8 100644 --- a/webhooks/functions/src/controller/handler/selection.ts +++ b/webhooks/functions/src/controller/handler/selection.ts @@ -19,8 +19,6 @@ export const selection = (app: Assistant) => { const enter: THandlerFn = async (m) => { - m.say("selection.enter.bookshelf", {number: 3}); - } const selectBook: THandlerFn = async (m) => { diff --git a/webhooks/functions/src/model/data.model.test.ts b/webhooks/functions/src/model/data.model.test.ts index 3c0e6b91..23b46fc6 100644 --- a/webhooks/functions/src/model/data.model.test.ts +++ b/webhooks/functions/src/model/data.model.test.ts @@ -21,6 +21,7 @@ export const freshDataClone = () => Object.assign({ kind: 'GROUP', url: '', nextUrlCounter: 0, + nbChoice: 0, from: 'main', }, }, @@ -30,7 +31,7 @@ export const freshDataClone = () => Object.assign({ }, }, {}); -export const parsedDataClone = (): IStorage => ({ +export const parsedDataClone = (): IStorage => Object.assign({ bearerToken: 'test', player: { current: { @@ -57,4 +58,4 @@ export const parsedDataClone = (): IStorage => ({ authentication: 'NO_LINKED', sessionId: '', }, -}); +}, {}) as IStorage; diff --git a/webhooks/functions/src/sdk/selection.test.ts b/webhooks/functions/src/sdk/selection.test.ts index 76400f86..87b7df26 100644 --- a/webhooks/functions/src/sdk/selection.test.ts +++ b/webhooks/functions/src/sdk/selection.test.ts @@ -5,7 +5,6 @@ import {headers, body} from './conv.test'; import {parsedDataClone} from '../model/data.model.test'; import {IOpdsResultView} from 'opds-fetcher-parser/build/src/interface/opds'; - chai.should(); const scene = 'selection'; @@ -56,11 +55,13 @@ describe(scene + ' handler', () => { const messageHelpers = (number: number, it: Array<[nb: number, title: string]>) => { const a = 'Pick one of these by saying their numbers.\n'; - const b = it.reduce((pv, [nb, title]) => `${nb}. ${title}\n`, ''); + const b = it.reduce((pv, [nb, title]) => pv + `${nb}. ${title}\n`, ''); const c = 'Which one would you like to start reading? Or perhaps you\'d like to explore the other titles on your bookshelf?\n'; return a + b + c; }; + const help = `Pick one out of 3 titles by mentioning their numbers. You can also ask for 'another one' or directly search by genre, author or book title.\nWhat would you like to do?\n`; + describe('app', () => { it('on enter', async () => { body.handler.name = 'selection__on_enter'; @@ -109,6 +110,9 @@ describe(scene + ' handler', () => { const message = `Oops, something went wrong. I will send you back to the home menu\n`; const pullData = parsedDataClone(); + + // DEFAULT : trigger an error + // pullData.session.scene.selection.state = 'DEFAULT'; const data = await expressMocked(body, headers, pullData); data.prompt.firstSimple.speech.should.to.be.eq(message); @@ -363,7 +367,7 @@ describe(scene + ' handler', () => { const pullData = parsedDataClone(); const model = await storageModelMocked(pullData); - const data = await expressMocked(body, headers, undefined, undefined, undefined, model); + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); data.scene.next.name.should.to.be.eq('selection'); model.data.store.session.scene.selection.state.should.to.be.eq('FINISH'); @@ -373,11 +377,94 @@ describe(scene + ' handler', () => { // need to check with google data }); - it('another one', async () => { + it('select book - number 10', async () => { + body.handler.name = 'selection__intent__selects_book'; + body.scene.name = scene; + body.intent.params = { + number: { + original: '10', + resolved: 10, + }, + }; + + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + + data.scene.next.name.should.to.be.eq('selection'); + data.prompt.firstSimple.speech.should.to.be.eq(help); + model.data.store.session.scene.selection.state.should.to.be.eq('DEFAULT'); // equals to original state + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); // reset + // or + // say the fallback message if type is incorrect + // need to check with google data + }); + + it('another one with machine not running', async () => { body.handler.name = 'selection__intent__another_one'; body.scene.name = scene; - const data = await expressMocked(body, headers); + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + + model.data.store.session.scene.selection.state.should.to.be.eq('DEFAULT'); // equals to original state + model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(0); // stay at 0 + model.data.store.session.scene.selection.url.should.to.be.eq(''); // reset + + data.scene.next.name.should.to.be.eq('selection'); + }); + + it('another one with machine running', async () => { + body.handler.name = 'selection__intent__another_one'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + pullData.session.scene.selection.state = 'RUNNING'; + pullData.session.scene.selection.url = 'http://my.url'; + pullData.session.scene.selection.nextUrlCounter = 3; + const model = await storageModelMocked(pullData); + const feed: Partial = {}; + // @ts-ignore + feed.links = { + next: [ + { + url: 'http://my.url.next', + }, + ], + }; + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); + + model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); // equals to original state + model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(4); // +1 + model.data.store.session.scene.selection.url.should.to.be.eq('http://my.url.next'); // reset + + data.scene.next.name.should.to.be.eq('selection'); + }); + + it('another one with machine running and no next link available', async () => { + body.handler.name = 'selection__intent__another_one'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + pullData.session.scene.selection.state = 'RUNNING'; + pullData.session.scene.selection.url = 'http://my.url'; + pullData.session.scene.selection.nextUrlCounter = 3; + const model = await storageModelMocked(pullData); + const feed: Partial = {}; + // @ts-ignore + feed.links = { + next: [ + ], + }; + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); + + model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); // equals to original state + model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(3); // 3 + model.data.store.session.scene.selection.url.should.to.be.eq('http://my.url'); // reset + + const message = 'no another results available'; + data.prompt.firstSimple.speech.should.to.be.eq(message); data.scene.next.name.should.to.be.eq('selection'); }); @@ -391,13 +478,10 @@ describe(scene + ' handler', () => { data.scene.next.name.should.to.be.eq('selection'); }); - const help = `Pick one out of 3 titles by mentioning their letter, A - B or C, or ask for their summary by saying 'Summary of A'. You can also ask for 'another one' or directly search by genre, author or book title.\nWhat would you like to do?\n`; - it('help', async () => { body.handler.name = 'selection__intent__help'; body.scene.name = scene; - const data = await expressMocked(body, headers); data.prompt.firstSimple.speech.should.to.be.eq(help); diff --git a/webhooks/functions/src/test/utils.test.ts b/webhooks/functions/src/test/utils.test.ts index 00d8f7e3..adca1219 100644 --- a/webhooks/functions/src/test/utils.test.ts +++ b/webhooks/functions/src/test/utils.test.ts @@ -61,7 +61,7 @@ export const fetcherMocked = (feed?: any, webpub?: Partial) => { return fetcher; }; -export const expressMocked = async (body: JsonObject, headers: JsonObject, pullData: IStorage | undefined = undefined, feed: Partial | undefined = undefined, webpub: Partial | undefined = undefined, data: any = undefined) => { +export const expressMocked = async (body: JsonObject, headers: JsonObject, pullData: IStorage | undefined = undefined, feed: Partial | undefined = undefined, webpub: Partial | undefined = undefined, data: StorageModel | undefined = undefined) => { if (!data) { ({data /* , push, pull*/} = await storageModelMocked(pullData)); } diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index e091b752..b47ef626 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -88,7 +88,8 @@ }, "lastPage": { "publication": "Here's the last available books", - "group": "Here's the last available groups" + "group": "Here's the last available groups", + "intent": "no another results available" }, "common": { "1": "Pick one of these by saying their numbers.", diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index ba1756b4..c934ca03 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", + "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.intent" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", + "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.intent" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } From 24301b4887c7adf25fbd42dfd410893f63b29a1a Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 15 Feb 2022 17:59:35 +0100 Subject: [PATCH 132/180] fix: webpub request Machine --- webhooks/functions/package-lock.json | 6 +++--- webhooks/functions/package.json | 4 +++- webhooks/functions/src/controller/Machine.ts | 16 ++++++++++------ 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/webhooks/functions/package-lock.json b/webhooks/functions/package-lock.json index 2af94221..cad82d1e 100644 --- a/webhooks/functions/package-lock.json +++ b/webhooks/functions/package-lock.json @@ -1047,9 +1047,9 @@ } }, "@types/validator": { - "version": "13.6.6", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.6.6.tgz", - "integrity": "sha512-+qogUELb4gMhrMjSh/seKmGVvN+uQLfyqJAqYRWqVHsvBsUO2xDBCL8CJ/ZSukbd8vXaoYbpIssAmfLEzzBHEw==" + "version": "13.7.1", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.1.tgz", + "integrity": "sha512-I6OUIZ5cYRk5lp14xSOAiXjWrfVoMZVjDuevBYgQDYzZIjsf2CAISpEcXOkFAtpAHbmWIDLcZObejqny/9xq5Q==" }, "@typescript-eslint/eslint-plugin": { "version": "5.3.1", diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index ea5c365f..c3f823ca 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -29,13 +29,15 @@ "firebase-functions": "^3.16.0", "i18next": "^21.5.3", "opds-fetcher-parser": "git+https://github.com/edrlab/opds_fetcher_parser.git#03a9eb705e05f4ebf02ea2815c47707aec8705c7", - "reflect-metadata": "^0.1.13" + "reflect-metadata": "^0.1.13", + "validator": "^13.7.0" }, "devDependencies": { "@types/chai": "^4.3.0", "@types/mocha": "^9.0.0", "@types/proxyquire": "^1.3.28", "@types/sinon": "^10.0.9", + "@types/validator": "^13.7.1", "@typescript-eslint/eslint-plugin": "^5.3.1", "@typescript-eslint/parser": "^5.3.1", "chai": "^4.3.6", diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index eee2ee69..5edd05bf 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -6,6 +6,7 @@ import {StorageModel} from '../model/storage.model'; import {i18n, TI18n, TI18nKey} from '../translation'; import {IConversationV3, TSdkScene2} from '../type'; import {resetSelection} from './handler/selection.helper'; +import validator from 'validator'; export class Machine { private _conv: IConversationV3; @@ -137,22 +138,25 @@ export class Machine { public async getCurrentPlayingTitleAndChapter() { ok(this._model); - const cur = this._model.store.player.current; + const cur = this._model.store.player.current + const url = cur.url || ""; const chapter = (cur.index || 0) + 1; - const {title, author} = await this.getTitleAndAuthorFromWebpub(cur.url); + const {title, author} = await this.getTitleAndAuthorFromWebpub(url); return {chapter, title, author}; } - public async getTitleAndAuthorFromWebpub(url) { - const webpub = await this.wepubRequest(url); + public async getTitleAndAuthorFromWebpub(url: string) { + const webpub = await this.webpubRequest(url); const title = webpub?.title || 'no title'; // @TODO i18n const author = (webpub?.authors || [])[0] || ''; return {title, author}; } - private async wepubRequest(url: string) { - // @TODO checks if url is valid + private async webpubRequest(url: string) { + if (!validator.isURL(url)) { + throw new Error("url not valid : " + url); + } const webpub = await this._fetcher?.webpubRequest(url); return webpub; } From e6b027fb4f712b40577a5edb1e34d9623f77fa74 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 15 Feb 2022 19:07:21 +0100 Subject: [PATCH 133/180] feat: selections select book instent --- webhooks/functions/src/constants.ts | 3 +- webhooks/functions/src/controller/Machine.ts | 39 ++++- .../src/controller/handler/selection.ts | 39 ++++- .../functions/src/model/data.model.test.ts | 3 +- webhooks/functions/src/sdk/conv.test.ts | 2 +- webhooks/functions/src/sdk/selection.test.ts | 142 +++++++++++++++--- webhooks/functions/src/test/utils.test.ts | 6 +- webhooks/functions/src/translation/en/en.json | 2 +- 8 files changed, 207 insertions(+), 29 deletions(-) diff --git a/webhooks/functions/src/constants.ts b/webhooks/functions/src/constants.ts index c862906c..c26a4b38 100644 --- a/webhooks/functions/src/constants.ts +++ b/webhooks/functions/src/constants.ts @@ -12,7 +12,8 @@ export const DEFAULT_LANGUAGE: TDefaultLanguage = 'en'; export type TDefaultLanguage = Extract; -export const PADDING = 5; +export const PADDING_GROUP = 5; +export const PADDING_PUB = 3; export const LAST_SEEN_THRESHOLD = 72; export const PROJECT_ID = 'edrlab-1'; diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 5edd05bf..3613aa52 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -153,14 +153,51 @@ export class Machine { return {title, author}; } + public get selectionSession() { + ok(this._model); + return this._model.store.session.scene.selection; + } + + public get selectBookNumber() { + return this._conv.intent.params?.number.resolved as number | undefined; + } + + public async getGroupSizeWithUrl(url: string) { + + const feed = await this.feedRequest(url); + const size = feed.groups?.length; + return size; + } + + public async getPublicationSizeWithUrl(url: string) { + + const feed = await this.feedRequest(url); + const size = feed.publications?.length; + return size; + } + private async webpubRequest(url: string) { if (!validator.isURL(url)) { throw new Error("url not valid : " + url); } - const webpub = await this._fetcher?.webpubRequest(url); + if (!this._fetcher) { + throw new Error("no fetcher available !"); + } + const webpub = await this._fetcher.webpubRequest(url); return webpub; } + private async feedRequest(url: string) { + if (!validator.isURL(url)) { + throw new Error("url not valid : " + url); + } + if (!this._fetcher) { + throw new Error("no fetcher available !"); + } + const feed = await this._fetcher.feedRequest(url); + return feed; + } + private removeSessionDataWhenNewUserSession() { if (!this._model) { return; diff --git a/webhooks/functions/src/controller/handler/selection.ts b/webhooks/functions/src/controller/handler/selection.ts index 9424e7b8..51d795db 100644 --- a/webhooks/functions/src/controller/handler/selection.ts +++ b/webhooks/functions/src/controller/handler/selection.ts @@ -1,4 +1,4 @@ -import { NAME } from "../../constants"; +import { NAME, PADDING_GROUP, PADDING_PUB } from "../../constants"; import { THandlerFn } from "../../type"; import { Assistant } from "../Assistant"; import { missing } from "./void"; @@ -22,7 +22,42 @@ const enter: THandlerFn = async (m) => { } const selectBook: THandlerFn = async (m) => { - + + const nb = m.selectBookNumber; + const kind = m.selectionSession.kind; + const padding = kind === "GROUP" ? PADDING_GROUP : PADDING_PUB; + const url = m.selectionSession.url; + + const size = kind === "GROUP" ? await m.getGroupSizeWithUrl(url) : await m.getPublicationSizeWithUrl(url); + + console.info("SELECT BOOK INTENT", nb, url, size); + + if (m.selectionSession.state === "DEFAULT") { + console.info("DEFAULT -> returns"); + m.selectionSession.nbChoice = 0; + + } else if (!nb) { + m.selectionSession.nbChoice = 0; + console.info("number from intent not defined"); + + } else if (!size) { + m.selectionSession.nbChoice = 0; + console.info("size from feed request undefined .. the url has failed? " + url); + + } else if (nb < 1) { + m.selectionSession.nbChoice = 0; + m.say('selection.help.1'); + + } else if (nb > padding || nb > size) { + m.selectionSession.nbChoice = 0; + m.say('selection.help.1'); + + } else { + // ok let's go + m.selectionSession.nbChoice = nb; + m.selectionSession.state = "FINISH"; + } + m.nextScene = 'selection'; } diff --git a/webhooks/functions/src/model/data.model.test.ts b/webhooks/functions/src/model/data.model.test.ts index 23b46fc6..f886a29c 100644 --- a/webhooks/functions/src/model/data.model.test.ts +++ b/webhooks/functions/src/model/data.model.test.ts @@ -28,6 +28,7 @@ export const freshDataClone = () => Object.assign({ }, user: { authentication: 'NO_LINKED', + sessionId: 'test', }, }, {}); @@ -56,6 +57,6 @@ export const parsedDataClone = (): IStorage => Object.assign({ }, user: { authentication: 'NO_LINKED', - sessionId: '', + sessionId: 'test', }, }, {}) as IStorage; diff --git a/webhooks/functions/src/sdk/conv.test.ts b/webhooks/functions/src/sdk/conv.test.ts index d602686e..d54d63cc 100644 --- a/webhooks/functions/src/sdk/conv.test.ts +++ b/webhooks/functions/src/sdk/conv.test.ts @@ -36,7 +36,7 @@ const bodyCopy = () => Object.assign({}, { 'slots': {}, }, 'session': { - 'id': 'ABwppHGoBsXu3JLKx1PW4N40zjedGWXq2Ln6bsc9POLhC2rshmkstBG-u7EAq2UZ7tjBRmoMgGc', + 'id': 'test', // remove id token but @todo need to test this part .. remove session when session id changed 'params': {}, 'typeOverrides': [], 'languageCode': '', diff --git a/webhooks/functions/src/sdk/selection.test.ts b/webhooks/functions/src/sdk/selection.test.ts index 87b7df26..b7a42b29 100644 --- a/webhooks/functions/src/sdk/selection.test.ts +++ b/webhooks/functions/src/sdk/selection.test.ts @@ -60,7 +60,7 @@ describe(scene + ' handler', () => { return a + b + c; }; - const help = `Pick one out of 3 titles by mentioning their numbers. You can also ask for 'another one' or directly search by genre, author or book title.\nWhat would you like to do?\n`; + const help = `Pick one out of 3 titles by mentioning their numbers. You can also ask for 'another one' or directly search by genre, author or book title.\n`; // What would you like to do?\n`; describe('app', () => { it('on enter', async () => { @@ -134,6 +134,51 @@ describe(scene + ' handler', () => { data.scene.next.name.should.to.be.eq('home_user'); }); + const newFeed = (): Partial => ({ + publications: [ + { + title: 'first publication', + baseUrl: '', + authors: [], + numberOfPages: 0, + }, + { + title: 'second publication', + baseUrl: '', + authors: [], + numberOfPages: 0, + }, + ], + groups: [ + { + selfLink: { + title: 'first group', + url: '', + } + }, + { + selfLink: { + title: 'second group', + url: '', + } + }, + // { + // selfLink: { + // title: 'third group', + // url: '', + // } + // }, + ], + // @ts-ignore + links: { + next: [ + { + url: "http://next.link" + } + ] + } + }); + const testStateRunningPublication = () => { const pullData = parsedDataClone(); pullData.session.scene.selection.state = 'RUNNING'; @@ -177,24 +222,24 @@ describe(scene + ' handler', () => { pullData.session.scene.selection.kind = 'GROUP'; const feed: Partial = { - publications: [ + groups: [ { - title: 'first group', - baseUrl: '', - authors: [], - numberOfPages: 0, + selfLink: { + title: 'first group', + url: '', + } }, { - title: 'second group', - baseUrl: '', - authors: [], - numberOfPages: 0, + selfLink: { + title: 'second group', + url: '', + } }, { - title: 'third group', - baseUrl: '', - authors: [], - numberOfPages: 0, + selfLink: { + title: 'third group', + url: '', + } }, ], }; @@ -354,7 +399,6 @@ describe(scene + ' handler', () => { // data.scene.next.name.should.to.be.eq('selection'); // }); - it('select book - number 1', async () => { body.handler.name = 'selection__intent__selects_book'; body.scene.name = scene; @@ -367,14 +411,66 @@ describe(scene + ' handler', () => { const pullData = parsedDataClone(); const model = await storageModelMocked(pullData); - const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + model.data.store.session.scene.selection.kind = "PUBLICATION"; + model.data.store.session.scene.selection.state = "RUNNING"; + model.data.store.session.scene.selection.url = "http://my.url"; + const feed = newFeed(); + feed.publications?.length.should.to.be.eq(2); + + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); data.scene.next.name.should.to.be.eq('selection'); model.data.store.session.scene.selection.state.should.to.be.eq('FINISH'); model.data.store.session.scene.selection.nbChoice.should.to.be.eq(1); - // or - // say the fallback message if type is incorrect - // need to check with google data + + }); + it('select book - number 2 ', async () => { + body.handler.name = 'selection__intent__selects_book'; + body.scene.name = scene; + body.intent.params = { + number: { + original: '2', + resolved: 2, + }, + }; + + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + model.data.store.session.scene.selection.kind = "PUBLICATION"; + model.data.store.session.scene.selection.state = "RUNNING"; + model.data.store.session.scene.selection.url = "http://my.url"; + const feed = newFeed(); + feed.publications?.length.should.to.be.eq(2); + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); + + data.scene.next.name.should.to.be.eq('selection'); + model.data.store.session.scene.selection.state.should.to.be.eq('FINISH'); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(2); + + }); + + it('select book - number 3 with only 2 pub available', async () => { + body.handler.name = 'selection__intent__selects_book'; + body.scene.name = scene; + body.intent.params = { + number: { + original: '3', + resolved: 3, + }, + }; + + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + model.data.store.session.scene.selection.kind = "PUBLICATION"; + model.data.store.session.scene.selection.url = "http://my.url"; + const feed = newFeed(); + feed.publications?.length.should.to.be.eq(2); + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); + + data.scene.next.name.should.to.be.eq('selection'); + model.data.store.session.scene.selection.state.should.to.be.eq('DEFAULT'); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); + }); it('select book - number 10', async () => { @@ -389,11 +485,15 @@ describe(scene + ' handler', () => { const pullData = parsedDataClone(); const model = await storageModelMocked(pullData); - const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + model.data.store.session.scene.selection.url = "http://my.url"; + model.data.store.session.scene.selection.state = 'RUNNING'; + model.data.store.session.scene.selection.kind = "PUBLICATION"; + const feed = newFeed(); + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); data.scene.next.name.should.to.be.eq('selection'); data.prompt.firstSimple.speech.should.to.be.eq(help); - model.data.store.session.scene.selection.state.should.to.be.eq('DEFAULT'); // equals to original state + model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); // equals to original state model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); // reset // or // say the fallback message if type is incorrect diff --git a/webhooks/functions/src/test/utils.test.ts b/webhooks/functions/src/test/utils.test.ts index adca1219..33a7c081 100644 --- a/webhooks/functions/src/test/utils.test.ts +++ b/webhooks/functions/src/test/utils.test.ts @@ -50,7 +50,7 @@ export const storageModelMocked = async (pullData: IStorage | undefined = undefi }; }; -export const fetcherMocked = (feed?: any, webpub?: Partial) => { +export const fetcherMocked = (feed?: Partial, webpub?: Partial) => { const fetcher = sinon.createStubInstance(OpdsFetcher, { // @ts-ignore feedRequest: sinon.stub().returns(Promise.resolve(feed)), @@ -63,7 +63,11 @@ export const fetcherMocked = (feed?: any, webpub?: Partial) => { export const expressMocked = async (body: JsonObject, headers: JsonObject, pullData: IStorage | undefined = undefined, feed: Partial | undefined = undefined, webpub: Partial | undefined = undefined, data: StorageModel | undefined = undefined) => { if (!data) { + console.log("NO DATA MOCKED YET"); + ({data /* , push, pull*/} = await storageModelMocked(pullData)); + } else { + console.log("DATA MOCKED"); } const fetcher = fetcherMocked(feed, webpub) as unknown as OpdsFetcher; diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index b47ef626..6b41161d 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -101,7 +101,7 @@ } }, "help": { - "1": "Pick one out of 3 titles by mentioning their letter, A - B or C, or ask for their summary by saying 'Summary of A'. You can also ask for 'another one' or directly search by genre, author or book title.", + "1": "Pick one out of 3 titles by mentioning their numbers. You can also ask for 'another one' or directly search by genre, author or book title.", "2": "What would you like to do?" } }, From 89e4a34eb01fc7fcc6ae3f3a334f4bbae94a8d25 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 16 Feb 2022 12:37:05 +0100 Subject: [PATCH 134/180] feat: player scene & lint & try to fix catch Assistant --- sdk/custom/scenes/player.yaml | 15 +++ sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 5 + .../functions/src/controller/Assistant.ts | 10 +- webhooks/functions/src/controller/Machine.ts | 111 ++++++++++++++++-- .../functions/src/controller/handler/index.ts | 2 + .../src/controller/handler/player.ts | 45 +++++++ webhooks/functions/src/sdk/conv.test.ts | 6 + webhooks/functions/src/sdk/player.test.ts | 87 ++++++++++++++ webhooks/functions/src/sdk/selection.test.ts | 107 ++++++++--------- webhooks/functions/src/test/utils.test.ts | 6 +- webhooks/functions/src/translation/en/en.json | 3 + .../functions/src/typings/sdkHandler.d.ts | 2 +- webhooks/functions/src/typings/sdkScene.d.ts | 2 +- 13 files changed, 327 insertions(+), 74 deletions(-) create mode 100644 sdk/custom/scenes/player.yaml create mode 100644 webhooks/functions/src/controller/handler/player.ts create mode 100644 webhooks/functions/src/sdk/player.test.ts diff --git a/sdk/custom/scenes/player.yaml b/sdk/custom/scenes/player.yaml new file mode 100644 index 00000000..e9c731a7 --- /dev/null +++ b/sdk/custom/scenes/player.yaml @@ -0,0 +1,15 @@ +intentEvents: +- handler: + webhookHandler: player__intent__media_status_finished + intent: actions.intent.MEDIA_STATUS_FINISHED +- handler: + webhookHandler: player__intent__media_status_paused + intent: actions.intent.MEDIA_STATUS_PAUSED +- handler: + webhookHandler: player__intent__media_status_stopped + intent: actions.intent.MEDIA_STATUS_STOPPED +- handler: + webhookHandler: player__intent__media_status_failed + intent: actions.intent.MEDIA_STATUS_FAILED +onEnter: + webhookHandler: player__on_enter diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index f5efb886..1c1584ba 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -64,6 +64,11 @@ handlers: - name: silence_1 - name: silence_2 - name: silence_end +- name: player__on_enter +- name: player__intent__media_status_finished +- name: player__intent__media_status_paused +- name: player__intent__media_status_stopped +- name: player__intent__media_status_failed httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/controller/Assistant.ts b/webhooks/functions/src/controller/Assistant.ts index 1bd7c181..93434baa 100644 --- a/webhooks/functions/src/controller/Assistant.ts +++ b/webhooks/functions/src/controller/Assistant.ts @@ -27,13 +27,11 @@ export class Assistant { console.error('APP CATCH ERROR', error); if (conv.scene.next) { - conv.scene.next.name = conv.scene.name; - } // loop + conv.scene.next.name = 'actions.scene.END_CONVERSATION'; + } - // @TODO - // the catch handle must exit (go to END SCENE) - // Inform the user of the unexpected error and exit the app - // usefull with a db corruption .. let's the user delete his google personnal storage to trigger a new BearerToken + // @TODO fix translation + conv.add('Oops, something went wrong. I will exit the app. Feel free to reopen it as soon as possible.'); }); if (storageModel) { diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 3613aa52..d2c4f533 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -7,6 +7,8 @@ import {i18n, TI18n, TI18nKey} from '../translation'; import {IConversationV3, TSdkScene2} from '../type'; import {resetSelection} from './handler/selection.helper'; import validator from 'validator'; +import {Media} from '@assistant/conversation'; +import {MediaType, OptionalMediaControl} from '@assistant/conversation/dist/api/schema'; export class Machine { private _conv: IConversationV3; @@ -138,8 +140,8 @@ export class Machine { public async getCurrentPlayingTitleAndChapter() { ok(this._model); - const cur = this._model.store.player.current - const url = cur.url || ""; + const cur = this._model.store.player.current; + const url = cur.url || ''; const chapter = (cur.index || 0) + 1; const {title, author} = await this.getTitleAndAuthorFromWebpub(url); @@ -163,25 +165,118 @@ export class Machine { } public async getGroupSizeWithUrl(url: string) { - const feed = await this.feedRequest(url); const size = feed.groups?.length; return size; } public async getPublicationSizeWithUrl(url: string) { - const feed = await this.feedRequest(url); const size = feed.publications?.length; return size; } + public persistMediaPlayer() { + ok(this._model); + + const _progress = this._conv.context?.media?.progress || '0'; + const progress = parseInt(_progress, 10); + const index = this._conv.request.context?.media?.index || 0; + const url = this._model.store.player.current.url; + if (!url) { + return; + } + if (!validator.isURL(url)) { + return; + } + + this._model.store.player.current.index = index; + this._model.store.player.current.time = progress; + this._model.store.player.current.playing = true; // always true + + this._model.store.player.history.set(url, { + index, + time: progress, + date: new Date(), + }); + } + + public mediaPlayerAck() { + this._conv.add(new Media({ + mediaType: MediaType.MediaStatusACK, + })); + } + + public get currentPlayingUrl() { + ok(this._model); + const url = this._model.store.player.current.url; + if (url && validator.isURL(url)) { + return url; + } + return undefined; + } + + public async player() { + ok(this._model); + const url = this.currentPlayingUrl; + if (!url) { + throw new Error('no playing url'); + } + + const startIndexRaw = this._model.store.player.current.index; + const startTimeRaw = this._model.store.player.current.time; + + const webpub = await this.webpubRequest(url); + if (!webpub) { + throw new Error('no webpub'); + } + + let startIndex = (startIndexRaw && startIndexRaw > -1 && startIndexRaw <= webpub.readingOrders.length) ? + startIndexRaw : + 0; + + const startTime = (startTimeRaw && startTimeRaw > -1) ? + startTimeRaw <= (webpub.readingOrders[startIndex].duration || Infinity) ? + startTimeRaw : + (startIndex += 1, startTimeRaw) : + 0; + + startIndex = startIndex <= webpub.readingOrders.length ? + startIndex : + 0; + + const mediaObjects = webpub.readingOrders + .map((v, i) => ({ + name: `${webpub.title || ''} - ${i + 1}`, + url: v.url, + image: { + large: { + alt: webpub.title, + url: webpub.cover || '', + }, + }, + })).slice(startIndex); + + console.log('Media list'); + console.log(mediaObjects); + console.log('Start Index = ', startIndex, ' Start Time = ', startTime, ' Start Time'); + + this._conv.add( + new Media({ + mediaObjects: mediaObjects, + mediaType: MediaType.Audio, + optionalMediaControls: [OptionalMediaControl.Paused, OptionalMediaControl.Stopped], + startOffset: `${startTime}s`, + }), + ); + } + private async webpubRequest(url: string) { if (!validator.isURL(url)) { - throw new Error("url not valid : " + url); + throw new Error('url not valid : ' + url); } if (!this._fetcher) { - throw new Error("no fetcher available !"); + throw new Error('no fetcher available !'); } const webpub = await this._fetcher.webpubRequest(url); return webpub; @@ -189,10 +284,10 @@ export class Machine { private async feedRequest(url: string) { if (!validator.isURL(url)) { - throw new Error("url not valid : " + url); + throw new Error('url not valid : ' + url); } if (!this._fetcher) { - throw new Error("no fetcher available !"); + throw new Error('no fetcher available !'); } const feed = await this._fetcher.feedRequest(url); return feed; diff --git a/webhooks/functions/src/controller/handler/index.ts b/webhooks/functions/src/controller/handler/index.ts index e095d48b..221a4b3a 100644 --- a/webhooks/functions/src/controller/handler/index.ts +++ b/webhooks/functions/src/controller/handler/index.ts @@ -5,6 +5,7 @@ import { home_new_user_no } from "./home_new_user_no"; import { home_user } from "./home_user"; import { info } from "./info"; import { main } from "./main"; +import { player } from "./player"; import { selection } from "./selection"; export const handler = (app = new Assistant({})) => { @@ -45,4 +46,5 @@ export const handler = (app = new Assistant({})) => { home_new_user_maybe_later(app); info(app); selection(app); + player(app); } diff --git a/webhooks/functions/src/controller/handler/player.ts b/webhooks/functions/src/controller/handler/player.ts new file mode 100644 index 00000000..eae593b4 --- /dev/null +++ b/webhooks/functions/src/controller/handler/player.ts @@ -0,0 +1,45 @@ +import { THandlerFn } from "../../type"; +import { Assistant } from "../Assistant"; + +export const player = (app: Assistant) => { + + app.handle("player__on_enter", enter); + app.handle("player__intent__media_status_stopped", stopped); + app.handle("player__intent__media_status_finished", finished); + app.handle("player__intent__media_status_paused", paused); + app.handle("player__intent__media_status_failed", failed); + +} + +const enter: THandlerFn = async (m) => { + + await m.player(); +} + +const stopped: THandlerFn = async (m) => { + + m.persistMediaPlayer(); + m.mediaPlayerAck(); + + m.nextScene = "actions.scene.END_CONVERSATION"; +} + +const paused: THandlerFn = async (m) => { + + m.persistMediaPlayer(); + m.mediaPlayerAck(); +} + +const failed: THandlerFn = async (m) => { + + m.say("error.1"); + m.nextScene = "home_user"; +} + + +const finished: THandlerFn = async (m) => { + + m.persistMediaPlayer(); + + m.nextScene = "home_user"; +}; \ No newline at end of file diff --git a/webhooks/functions/src/sdk/conv.test.ts b/webhooks/functions/src/sdk/conv.test.ts index d54d63cc..6fcb2ba4 100644 --- a/webhooks/functions/src/sdk/conv.test.ts +++ b/webhooks/functions/src/sdk/conv.test.ts @@ -67,6 +67,12 @@ const bodyCopy = () => Object.assign({}, { 'version': '', }, }, + 'context': { + 'media': { + progress: '0s', + index: 0, + }, + }, }); export const convRequestInHandle = { diff --git a/webhooks/functions/src/sdk/player.test.ts b/webhooks/functions/src/sdk/player.test.ts new file mode 100644 index 00000000..7df49187 --- /dev/null +++ b/webhooks/functions/src/sdk/player.test.ts @@ -0,0 +1,87 @@ +import {expressMocked, shell, storageModelMocked} from '../test/utils.test'; +import * as chai from 'chai'; +// import * as sinon from 'sinon'; +import {headers, body} from './conv.test'; +import {parsedDataClone} from '../model/data.model.test'; + +/* eslint-disable no-unused-vars */ + +chai.should(); + +const scene = 'player'; + +const yaml = `intentEvents: +- handler: + webhookHandler: player__intent__media_status_finished + intent: actions.intent.MEDIA_STATUS_FINISHED +- handler: + webhookHandler: player__intent__media_status_paused + intent: actions.intent.MEDIA_STATUS_PAUSED +- handler: + webhookHandler: player__intent__media_status_stopped + intent: actions.intent.MEDIA_STATUS_STOPPED +- handler: + webhookHandler: player__intent__media_status_failed + intent: actions.intent.MEDIA_STATUS_FAILED +onEnter: + webhookHandler: player__on_enter +`; + +describe(scene + ' handler', () => { + describe('sdk', () => { + it('check main scene', (done) => { + shell(`cat custom/scenes/${scene}.yaml`, (stdout) => { + stdout.should.to.be.eq(yaml); + }, done); + }); + }); + + describe('app', () => { + it('on enter', async () => { + body.handler.name = 'player__on_enter'; + body.scene.name = scene; + + // NO TEST YET + const data = await expressMocked(body, headers); + }); + it('media status finished', async () => { + body.handler.name = 'player__intent__media_status_finished'; + body.scene.name = scene; + body.context.media.index = 2; + body.context.media.progress = '40s'; + + const pullData = parsedDataClone(); + pullData.player.current.index = 0; + pullData.player.current.time = 0; + pullData.player.current.url = 'http://my.url'; + const model = await storageModelMocked(pullData); + + const webpub = undefined; + + const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); + + model.data.store.player.current.index = 2; + model.data.store.player.current.playing.should.to.be.eq(true); + model.data.store.player.current.time?.should.to.be.eq(40); + model.data.store.player.current.url?.should.to.be.eq('http://my.url'); + }); + it('media status stopped', async () => { + body.handler.name = 'player__intent__media_status_stopped'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + }); + it('media status paused', async () => { + body.handler.name = 'player__intent__media_status_stopped'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + }); + it('media status failed', async () => { + body.handler.name = 'player__intent__media_status_failed'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + }); + }); +}); diff --git a/webhooks/functions/src/sdk/selection.test.ts b/webhooks/functions/src/sdk/selection.test.ts index b7a42b29..03d85e78 100644 --- a/webhooks/functions/src/sdk/selection.test.ts +++ b/webhooks/functions/src/sdk/selection.test.ts @@ -135,49 +135,49 @@ describe(scene + ' handler', () => { }); const newFeed = (): Partial => ({ - publications: [ - { - title: 'first publication', - baseUrl: '', - authors: [], - numberOfPages: 0, - }, - { - title: 'second publication', - baseUrl: '', - authors: [], - numberOfPages: 0, + publications: [ + { + title: 'first publication', + baseUrl: '', + authors: [], + numberOfPages: 0, + }, + { + title: 'second publication', + baseUrl: '', + authors: [], + numberOfPages: 0, + }, + ], + groups: [ + { + selfLink: { + title: 'first group', + url: '', }, - ], - groups: [ - { - selfLink: { - title: 'first group', - url: '', - } + }, + { + selfLink: { + title: 'second group', + url: '', }, + }, + // { + // selfLink: { + // title: 'third group', + // url: '', + // } + // }, + ], + // @ts-ignore + links: { + next: [ { - selfLink: { - title: 'second group', - url: '', - } + url: 'http://next.link', }, - // { - // selfLink: { - // title: 'third group', - // url: '', - // } - // }, ], - // @ts-ignore - links: { - next: [ - { - url: "http://next.link" - } - ] - } - }); + }, + }); const testStateRunningPublication = () => { const pullData = parsedDataClone(); @@ -227,19 +227,19 @@ describe(scene + ' handler', () => { selfLink: { title: 'first group', url: '', - } + }, }, { selfLink: { title: 'second group', url: '', - } + }, }, { selfLink: { title: 'third group', url: '', - } + }, }, ], }; @@ -411,18 +411,17 @@ describe(scene + ' handler', () => { const pullData = parsedDataClone(); const model = await storageModelMocked(pullData); - model.data.store.session.scene.selection.kind = "PUBLICATION"; - model.data.store.session.scene.selection.state = "RUNNING"; - model.data.store.session.scene.selection.url = "http://my.url"; + model.data.store.session.scene.selection.kind = 'PUBLICATION'; + model.data.store.session.scene.selection.state = 'RUNNING'; + model.data.store.session.scene.selection.url = 'http://my.url'; const feed = newFeed(); feed.publications?.length.should.to.be.eq(2); - + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); data.scene.next.name.should.to.be.eq('selection'); model.data.store.session.scene.selection.state.should.to.be.eq('FINISH'); model.data.store.session.scene.selection.nbChoice.should.to.be.eq(1); - }); it('select book - number 2 ', async () => { body.handler.name = 'selection__intent__selects_book'; @@ -436,9 +435,9 @@ describe(scene + ' handler', () => { const pullData = parsedDataClone(); const model = await storageModelMocked(pullData); - model.data.store.session.scene.selection.kind = "PUBLICATION"; - model.data.store.session.scene.selection.state = "RUNNING"; - model.data.store.session.scene.selection.url = "http://my.url"; + model.data.store.session.scene.selection.kind = 'PUBLICATION'; + model.data.store.session.scene.selection.state = 'RUNNING'; + model.data.store.session.scene.selection.url = 'http://my.url'; const feed = newFeed(); feed.publications?.length.should.to.be.eq(2); const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); @@ -446,7 +445,6 @@ describe(scene + ' handler', () => { data.scene.next.name.should.to.be.eq('selection'); model.data.store.session.scene.selection.state.should.to.be.eq('FINISH'); model.data.store.session.scene.selection.nbChoice.should.to.be.eq(2); - }); it('select book - number 3 with only 2 pub available', async () => { @@ -461,8 +459,8 @@ describe(scene + ' handler', () => { const pullData = parsedDataClone(); const model = await storageModelMocked(pullData); - model.data.store.session.scene.selection.kind = "PUBLICATION"; - model.data.store.session.scene.selection.url = "http://my.url"; + model.data.store.session.scene.selection.kind = 'PUBLICATION'; + model.data.store.session.scene.selection.url = 'http://my.url'; const feed = newFeed(); feed.publications?.length.should.to.be.eq(2); const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); @@ -470,7 +468,6 @@ describe(scene + ' handler', () => { data.scene.next.name.should.to.be.eq('selection'); model.data.store.session.scene.selection.state.should.to.be.eq('DEFAULT'); model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); - }); it('select book - number 10', async () => { @@ -485,9 +482,9 @@ describe(scene + ' handler', () => { const pullData = parsedDataClone(); const model = await storageModelMocked(pullData); - model.data.store.session.scene.selection.url = "http://my.url"; + model.data.store.session.scene.selection.url = 'http://my.url'; model.data.store.session.scene.selection.state = 'RUNNING'; - model.data.store.session.scene.selection.kind = "PUBLICATION"; + model.data.store.session.scene.selection.kind = 'PUBLICATION'; const feed = newFeed(); const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); diff --git a/webhooks/functions/src/test/utils.test.ts b/webhooks/functions/src/test/utils.test.ts index 33a7c081..552a851d 100644 --- a/webhooks/functions/src/test/utils.test.ts +++ b/webhooks/functions/src/test/utils.test.ts @@ -63,11 +63,11 @@ export const fetcherMocked = (feed?: Partial, webpub?: Partial< export const expressMocked = async (body: JsonObject, headers: JsonObject, pullData: IStorage | undefined = undefined, feed: Partial | undefined = undefined, webpub: Partial | undefined = undefined, data: StorageModel | undefined = undefined) => { if (!data) { - console.log("NO DATA MOCKED YET"); - + console.log('NO DATA MOCKED YET'); + ({data /* , push, pull*/} = await storageModelMocked(pullData)); } else { - console.log("DATA MOCKED"); + console.log('DATA MOCKED'); } const fetcher = fetcherMocked(feed, webpub) as unknown as OpdsFetcher; diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index 6b41161d..6668749d 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -105,6 +105,9 @@ "2": "What would you like to do?" } }, + "player": { + "start": "I start reading {{- title}}" + }, "void": "need to replace this message", "bye": { "1": "Thank you for trying the app. To pick up your reading again, come back any time" diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index b453a8fd..11b03c96 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'bookshelf__on_enter' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end'; +export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'bookshelf__on_enter' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end' | 'player__on_enter' | 'player__intent__media_status_finished' | 'player__intent__media_status_paused' | 'player__intent__media_status_stopped' | 'player__intent__media_status_failed'; diff --git a/webhooks/functions/src/typings/sdkScene.d.ts b/webhooks/functions/src/typings/sdkScene.d.ts index 64edf2e3..6e37cd58 100644 --- a/webhooks/functions/src/typings/sdkScene.d.ts +++ b/webhooks/functions/src/typings/sdkScene.d.ts @@ -1,4 +1,4 @@ // npm run scene-typed ; -export type TSdkScene = 'bookshelf' | 'collections' | 'home_new_user' | 'home_new_user_AccountLinking' | 'home_new_user_maybe_later' | 'home_new_user_no' | 'home_user' | 'info' | 'search' | 'selection'; +export type TSdkScene = 'bookshelf' | 'collections' | 'home_new_user' | 'home_new_user_AccountLinking' | 'home_new_user_maybe_later' | 'home_new_user_no' | 'home_user' | 'info' | 'player' | 'search' | 'selection'; From 1e0929b457981ae5c53e4159e917998dbdce15f6 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 16 Feb 2022 12:38:43 +0100 Subject: [PATCH 135/180] some imprve comment --- webhooks/functions/src/controller/Machine.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index d2c4f533..be9d1990 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -229,6 +229,7 @@ export class Machine { const webpub = await this.webpubRequest(url); if (!webpub) { throw new Error('no webpub'); + // @TODO how to handle these errors : just tell it to the user that the webpub is not readable and must choice an another } let startIndex = (startIndexRaw && startIndexRaw > -1 && startIndexRaw <= webpub.readingOrders.length) ? From 5ef24fbc223194abcbb0c99ca577b6f466228757 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 16 Feb 2022 15:55:53 +0100 Subject: [PATCH 136/180] feat: another-one selection handler with test checks --- webhooks/functions/src/controller/Machine.ts | 82 +++++++++- .../src/controller/handler/selection.ts | 19 +++ webhooks/functions/src/sdk/selection.test.ts | 145 +++++++++++++++++- webhooks/functions/src/translation/en/en.json | 2 +- webhooks/functions/src/typings/i18n.d.ts | 4 +- 5 files changed, 240 insertions(+), 12 deletions(-) diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index be9d1990..9823715b 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -1,6 +1,6 @@ import {ok} from 'assert'; import {AuthenticationStorage, http as httpOpdsFetcherParser, OpdsFetcher} from 'opds-fetcher-parser'; -import {API_BASE_URL, LAST_SEEN_THRESHOLD} from '../constants'; +import {API_BASE_URL, LAST_SEEN_THRESHOLD, PADDING_GROUP, PADDING_PUB} from '../constants'; import {TKeySessionScene, TStateAuthentication} from '../model/storage.interface'; import {StorageModel} from '../model/storage.model'; import {i18n, TI18n, TI18nKey} from '../translation'; @@ -9,6 +9,7 @@ import {resetSelection} from './handler/selection.helper'; import validator from 'validator'; import {Media} from '@assistant/conversation'; import {MediaType, OptionalMediaControl} from '@assistant/conversation/dist/api/schema'; +import {IOpdsLinkView} from 'opds-fetcher-parser/build/src/interface/opds'; export class Machine { private _conv: IConversationV3; @@ -164,6 +165,76 @@ export class Machine { return this._conv.intent.params?.number.resolved as number | undefined; } + public async getNexLinkPublicationWithUrl(url: string) { + const feed = await this.feedRequest(url); + const nextUrl = feed.links?.next[0].url; + + if (this.isValidHttpUrl(nextUrl) && await this.isPublicationAvailable(nextUrl)) { + return nextUrl; + } + return undefined; + } + + public async getNexLinkGroupWithUrl(url: string) { + const feed = await this.feedRequest(url); + const nextUrl = feed.links?.next[0].url; + if (this.isValidHttpUrl(nextUrl) && await this.isGroupAvailable(nextUrl)) { + return nextUrl; + } + return undefined; + } + + public async isPublicationAvailable(url: string) { + const {publication} = await this.getPublicationFromFeed(url); + if (publication.length) { + return true; + } + return false; + } + + public async getPublicationFromFeed(url: string) { + const feed = await this.feedRequest(url); + + const list = (feed.publications || []) + .filter(({openAccessLinks: l}) /* : l is IOpdsLinkView[]*/ => { + return ( + Array.isArray(l) && + l[0] && + this.isValidHttpUrl(l[0].url) + ); + }) + .slice(0, PADDING_PUB) + .map(({title, authors, openAccessLinks}) => ({ + title: title, + author: Array.isArray(authors) && authors.length ? authors[0].name : '', + webpubUrl: (openAccessLinks as IOpdsLinkView[])[0].url, + })); + return {publication: list, length: feed.metadata?.numberOfItems || list.length}; + } + + public async isGroupAvailable(url: string) { + const {groups} = await this.getGroupsFromFeed(url); + if (groups.length) { + return true; + } + return false; + } + + public async getGroupsFromFeed(url: string) { + const feed = await this.feedRequest(url); + + const list = (feed.groups || []) + .filter(({selfLink: l}) /* : l is IOpdsLinkView[]*/ => { + return l?.title && l?.url && this.isValidHttpUrl(l.url); + }) + .slice(0, PADDING_GROUP) + .map(({selfLink: {title, url}}) => ({ + title: title, + groupUrl: url, + })); + return {groups: list, length: feed.metadata?.numberOfItems || list.length}; + } + public async getGroupSizeWithUrl(url: string) { const feed = await this.feedRequest(url); const size = feed.groups?.length; @@ -322,4 +393,13 @@ export class Machine { this._model.store.user.sessionId = id; } } + + private isValidHttpUrl(url: string | undefined): url is string { + if (url && validator.isURL(url, { + protocols: ['https', 'http'], + })) { + return true; + } + return false; + } } diff --git a/webhooks/functions/src/controller/handler/selection.ts b/webhooks/functions/src/controller/handler/selection.ts index 51d795db..4d7b85ee 100644 --- a/webhooks/functions/src/controller/handler/selection.ts +++ b/webhooks/functions/src/controller/handler/selection.ts @@ -63,6 +63,25 @@ const selectBook: THandlerFn = async (m) => { const anotherOne: THandlerFn = async (m) => { + const { state, url } = m.selectionSession; + + if (state === "DEFAULT") { + throw new Error("DEFAULT mode not allowed with another one intent"); + } + + if (state === "RUNNING") { + + const kind = m.selectionSession.kind; + const nextUrl = kind === "GROUP" ? await m.getNexLinkGroupWithUrl(url) : await m.getNexLinkPublicationWithUrl(url); + + if (nextUrl) { + m.selectionSession.url = nextUrl; + m.selectionSession.nextUrlCounter++; + } else { + m.say("selection.enter.lastPage.notAvailable"); + } + } + m.nextScene = 'selection'; } diff --git a/webhooks/functions/src/sdk/selection.test.ts b/webhooks/functions/src/sdk/selection.test.ts index 03d85e78..12061147 100644 --- a/webhooks/functions/src/sdk/selection.test.ts +++ b/webhooks/functions/src/sdk/selection.test.ts @@ -137,14 +137,24 @@ describe(scene + ' handler', () => { const newFeed = (): Partial => ({ publications: [ { + openAccessLinks: [ + { + url: 'http://pub.url', + }, + ], + baseUrl: 'http://base.url', title: 'first publication', - baseUrl: '', authors: [], numberOfPages: 0, }, { + openAccessLinks: [ + { + url: 'http://pub.url', + }, + ], + baseUrl: 'http://base.url', title: 'second publication', - baseUrl: '', authors: [], numberOfPages: 0, }, @@ -153,13 +163,13 @@ describe(scene + ' handler', () => { { selfLink: { title: 'first group', - url: '', + url: 'http://group.url', }, }, { selfLink: { title: 'second group', - url: '', + url: 'http://group.url', }, }, // { @@ -509,10 +519,42 @@ describe(scene + ' handler', () => { model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(0); // stay at 0 model.data.store.session.scene.selection.url.should.to.be.eq(''); // reset + // catch trap + const message = 'Oops, something went wrong. I will exit the app. Feel free to reopen it as soon as possible.'; + data.prompt.firstSimple.speech.should.to.be.eq(message); + + data.scene.next.name.should.to.be.eq('actions.scene.END_CONVERSATION'); + }); + + it('another one with machine running but next link url is good with no publication available', async () => { + body.handler.name = 'selection__intent__another_one'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + pullData.session.scene.selection.state = 'RUNNING'; + pullData.session.scene.selection.url = 'http://my.url'; + pullData.session.scene.selection.nextUrlCounter = 3; + pullData.session.scene.selection.kind = 'PUBLICATION'; + const model = await storageModelMocked(pullData); + const feed: Partial = {}; + // @ts-ignore + feed.links = { + next: [ + { + url: 'http://my.url.next', + }, + ], + }; + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); + + model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); // equals to original state + model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(3); // +1 + model.data.store.session.scene.selection.url.should.to.be.eq('http://my.url'); // reset + data.scene.next.name.should.to.be.eq('selection'); }); - it('another one with machine running', async () => { + it('another one with machine running but next link url is good with no groups available', async () => { body.handler.name = 'selection__intent__another_one'; body.scene.name = scene; @@ -533,13 +575,69 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); // equals to original state + model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(3); // +1 + model.data.store.session.scene.selection.url.should.to.be.eq('http://my.url'); // reset + + data.scene.next.name.should.to.be.eq('selection'); + }); + + it('another one with machine running - publication', async () => { + body.handler.name = 'selection__intent__another_one'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + pullData.session.scene.selection.state = 'RUNNING'; + pullData.session.scene.selection.url = 'http://my.url'; + pullData.session.scene.selection.nextUrlCounter = 3; + pullData.session.scene.selection.kind = 'PUBLICATION'; + const model = await storageModelMocked(pullData); + const feed: Partial = newFeed(); + // @ts-ignore + feed.links = { + next: [ + { + url: 'http://my.url.next', + }, + ], + }; + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); + + model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); // equals to original state + model.data.store.session.scene.selection.url.should.to.be.eq('http://my.url.next'); // reset model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(4); // +1 + + data.scene.next.name.should.to.be.eq('selection'); + }); + + it('another one with machine running - group', async () => { + body.handler.name = 'selection__intent__another_one'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + pullData.session.scene.selection.state = 'RUNNING'; + pullData.session.scene.selection.url = 'http://my.url'; + pullData.session.scene.selection.nextUrlCounter = 3; + pullData.session.scene.selection.kind = 'GROUP'; + const model = await storageModelMocked(pullData); + const feed: Partial = newFeed(); + // @ts-ignore + feed.links = { + next: [ + { + url: 'http://my.url.next', + }, + ], + }; + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); + + model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); // equals to original state model.data.store.session.scene.selection.url.should.to.be.eq('http://my.url.next'); // reset + model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(4); // +1 data.scene.next.name.should.to.be.eq('selection'); }); - it('another one with machine running and no next link available', async () => { + it('another one with machine running and no next link available - publication', async () => { body.handler.name = 'selection__intent__another_one'; body.scene.name = scene; @@ -547,11 +645,42 @@ describe(scene + ' handler', () => { pullData.session.scene.selection.state = 'RUNNING'; pullData.session.scene.selection.url = 'http://my.url'; pullData.session.scene.selection.nextUrlCounter = 3; + pullData.session.scene.selection.kind = 'PUBLICATION'; const model = await storageModelMocked(pullData); - const feed: Partial = {}; + const feed: Partial = newFeed(); + // @ts-ignore + feed.links = { + next: [ + {url: ''}, + ], + }; + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); + + model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); // equals to original state + model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(3); // 3 + model.data.store.session.scene.selection.url.should.to.be.eq('http://my.url'); // reset + + const message = 'no another results available\n'; + data.prompt.firstSimple.speech.should.to.be.eq(message); + + data.scene.next.name.should.to.be.eq('selection'); + }); + + it('another one with machine running and no next link available - group', async () => { + body.handler.name = 'selection__intent__another_one'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + pullData.session.scene.selection.state = 'RUNNING'; + pullData.session.scene.selection.url = 'http://my.url'; + pullData.session.scene.selection.nextUrlCounter = 3; + pullData.session.scene.selection.kind = 'GROUP'; + const model = await storageModelMocked(pullData); + const feed: Partial = newFeed(); // @ts-ignore feed.links = { next: [ + {url: ''}, ], }; const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); @@ -560,7 +689,7 @@ describe(scene + ' handler', () => { model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(3); // 3 model.data.store.session.scene.selection.url.should.to.be.eq('http://my.url'); // reset - const message = 'no another results available'; + const message = 'no another results available\n'; data.prompt.firstSimple.speech.should.to.be.eq(message); data.scene.next.name.should.to.be.eq('selection'); diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index 6668749d..4301692f 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -89,7 +89,7 @@ "lastPage": { "publication": "Here's the last available books", "group": "Here's the last available groups", - "intent": "no another results available" + "notAvailable": "no another results available" }, "common": { "1": "Pick one of these by saying their numbers.", diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index c934ca03..beea4c76 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.intent" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", + "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "player.start" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.intent" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", + "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:player.start" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } From cc6ad7d4c2405ff6c554f3cd74325a10a658bddb Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 16 Feb 2022 16:00:04 +0100 Subject: [PATCH 137/180] fix: test storage --- webhooks/functions/src/model/data.model.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webhooks/functions/src/model/data.model.test.ts b/webhooks/functions/src/model/data.model.test.ts index f886a29c..9a2ef73b 100644 --- a/webhooks/functions/src/model/data.model.test.ts +++ b/webhooks/functions/src/model/data.model.test.ts @@ -28,7 +28,7 @@ export const freshDataClone = () => Object.assign({ }, user: { authentication: 'NO_LINKED', - sessionId: 'test', + // sessionId: 'test', }, }, {}); From d76c79cd0f4a3556d44c59dd75344bd24a0d4567 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 16 Feb 2022 16:08:26 +0100 Subject: [PATCH 138/180] fix: player on enter error --- webhooks/functions/src/sdk/player.test.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/webhooks/functions/src/sdk/player.test.ts b/webhooks/functions/src/sdk/player.test.ts index 7df49187..2114f8e6 100644 --- a/webhooks/functions/src/sdk/player.test.ts +++ b/webhooks/functions/src/sdk/player.test.ts @@ -37,12 +37,19 @@ describe(scene + ' handler', () => { }); describe('app', () => { - it('on enter', async () => { + it('on enter with no playing url', async () => { body.handler.name = 'player__on_enter'; body.scene.name = scene; - // NO TEST YET const data = await expressMocked(body, headers); + + const message = 'Oops, something went wrong. I will exit the app. Feel free to reopen it as soon as possible.'; + + data.prompt.firstSimple.speech.should.to.be.eq(message); + + // catch trap + + data.scene.next.name.should.to.be.eq('actions.scene.END_CONVERSATION'); }); it('media status finished', async () => { body.handler.name = 'player__intent__media_status_finished'; From 703d0442a780077d63b6238698de4f63128ea842 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 16 Feb 2022 16:45:02 +0100 Subject: [PATCH 139/180] fix: selection test help' --- webhooks/functions/src/controller/handler/selection.ts | 2 +- webhooks/functions/src/sdk/selection.test.ts | 2 +- webhooks/functions/src/translation/en/en.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/webhooks/functions/src/controller/handler/selection.ts b/webhooks/functions/src/controller/handler/selection.ts index 4d7b85ee..3a2cf34f 100644 --- a/webhooks/functions/src/controller/handler/selection.ts +++ b/webhooks/functions/src/controller/handler/selection.ts @@ -88,7 +88,7 @@ const anotherOne: THandlerFn = async (m) => { const help: THandlerFn = (m) => { m.say("selection.help.1"); - m.say("selection.help.2"); + // m.say("selection.help.2"); m.nextScene = "selection"; } diff --git a/webhooks/functions/src/sdk/selection.test.ts b/webhooks/functions/src/sdk/selection.test.ts index 12061147..2d711e4e 100644 --- a/webhooks/functions/src/sdk/selection.test.ts +++ b/webhooks/functions/src/sdk/selection.test.ts @@ -60,7 +60,7 @@ describe(scene + ' handler', () => { return a + b + c; }; - const help = `Pick one out of 3 titles by mentioning their numbers. You can also ask for 'another one' or directly search by genre, author or book title.\n`; // What would you like to do?\n`; + const help = `Pick one out of 3 titles by mentioning their numbers. You can also ask for 'another one'.\n` // What would you like to do?\n`; describe('app', () => { it('on enter', async () => { diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index 4301692f..cc6792e2 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -101,7 +101,7 @@ } }, "help": { - "1": "Pick one out of 3 titles by mentioning their numbers. You can also ask for 'another one' or directly search by genre, author or book title.", + "1": "Pick one out of 3 titles by mentioning their numbers. You can also ask for 'another one'.", "2": "What would you like to do?" } }, From 1680963eed3104e0f962f9439a53044733e33f16 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 16 Feb 2022 19:51:25 +0100 Subject: [PATCH 140/180] feat: selection on-enter in progress --- webhooks/functions/src/controller/Machine.ts | 75 +++++++++++++++++++ .../src/controller/handler/selection.ts | 73 ++++++++++++++++++ webhooks/functions/src/sdk/selection.test.ts | 15 ++++ 3 files changed, 163 insertions(+) diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 9823715b..986d6ad2 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -161,6 +161,81 @@ export class Machine { return this._model.store.session.scene.selection; } + public get playerCurrent() { + ok(this._model); + return this._model.store.player.current; + } + + public async selectGroup(url: string, number: number) { + ok(this._model); + if (!this.isValidHttpUrl(url)) { + throw new Error("url not valid"); + } + + const group = await this.getGroupFromNumberInSelectionWithUrl(url, number); + if (group) { + const groupUrl = group.groupUrl; + if (!this.isValidHttpUrl(groupUrl)) { + throw new Error("group url not valid"); + } + this.selectionSession.url = group.groupUrl; + this.selectionSession.kind = "PUBLICATION"; // set to publication mode + this.selectionSession.nextUrlCounter = 0; // reset + this.selectionSession.state = "RUNNING"; + + return true; + } + return false; + } + + public async selectPublication(url: string, number: number) { + ok(this._model); + if (!this.isValidHttpUrl(url)) { + throw new Error("url not valid"); + } + + const pub = await this.getPublicationFromNumberInSelectionWithUrl(url, number); + if (pub) { + const webpubUrl = pub.webpubUrl; + if (!this.isValidHttpUrl(webpubUrl)) { + throw new Error("webpub url not valid"); + } + this.initPlayerCurrentWithWebpubUrl(pub.webpubUrl); + + return true; + } + return false; + } + + public initPlayerCurrentWithWebpubUrl(webpubUrl: string) { + ok(this._model); + const pubFromHistory = this._model.store.player.history.get(webpubUrl); + this.playerCurrent.index = pubFromHistory?.index ?? 0; + this.playerCurrent.playing = true; + this.playerCurrent.time = pubFromHistory?.time ?? 0; + this.playerCurrent.url = webpubUrl; + } + + public async getPublicationFromNumberInSelectionWithUrl(url: string, number: number) { + const {publication} = await this.getPublicationFromFeed(url); + + const pub = publication[number - 1]; + if (pub) { + return pub; + } + return undefined; + } + + public async getGroupFromNumberInSelectionWithUrl(url: string, number: number) { + const {groups} = await this.getGroupsFromFeed(url); + + const group = groups[number - 1]; + if (group) { + return group; + } + return undefined; + } + public get selectBookNumber() { return this._conv.intent.params?.number.resolved as number | undefined; } diff --git a/webhooks/functions/src/controller/handler/selection.ts b/webhooks/functions/src/controller/handler/selection.ts index 3a2cf34f..2a02eb03 100644 --- a/webhooks/functions/src/controller/handler/selection.ts +++ b/webhooks/functions/src/controller/handler/selection.ts @@ -19,6 +19,79 @@ export const selection = (app: Assistant) => { const enter: THandlerFn = async (m) => { + const { state, url, nbChoice } = m.selectionSession; + const kind = m.selectionSession.kind; + + if (state === "RUNNING") { + + const isEmpty = kind === "GROUP" ? await m.isGroupAvailable(url) : await m.isPublicationAvailable(url); + if (isEmpty) { + m.say('selection.enter.empty.1'); + m.nextScene = "home_user"; + return ; + } + + const handler = m.selectionSession.from; + // intro + if (handler === "home_user__intent__bookshelf") { + const {publication} = await m.getPublicationFromFeed(url); // @TODO fix it .. twice call to api + m.say('selection.enter.bookshelf.first', {number: publication.length}); + } else if (handler === "home_user__intent__search") { + const {length} = await m.getPublicationFromFeed(url); // @TODO fix it .. twice call to api + m.say('selection.enter.search', {number: length}); + } + // @TODO handle collection group or publication + + // list groups or publication + m.say('selection.enter.common.1'); + const list = kind === "GROUP" + ? (await m.getGroupsFromFeed(url)).groups.map(({title}) => title) + : (await m.getPublicationFromFeed(url)).publication.map(({title}) => title); + list.forEach((title, i) => m.say('selection.enter.common.2', {symbol: i + 1, title})); + m.say('selection.enter.common.3'); + + + // outro + if (handler === "home_user__intent__bookshelf") { + m.say('selection.enter.bookshelf.second'); + } + + } else if (state === "FINISH") { + + const valid = kind === "GROUP" ? await m.selectGroup(url, nbChoice) : await m.selectPublication(url, nbChoice); + + if (valid) { + // select OK + + const { state } = m.selectionSession; + if (state === "RUNNING") { + // group requested + m.nextScene = "selection"; + } + + // const handler = m.selectionSession.from; + // is it usefull ? + // routing table + // all 'handler from' route to player ? + + m.nextScene = "player"; + // @TODO set the next-scene to player prequel + // lecture en cours ou annonciation du titre + + } else { + // KO + // help message + m.say("selection.help.1"); + m.nextScene = "selection"; + } + } else { + throw new Error("undefined selection state"); + // @TODO + // reset selection session + // move to home user + } + m.nextScene = "selection"; + } const selectBook: THandlerFn = async (m) => { diff --git a/webhooks/functions/src/sdk/selection.test.ts b/webhooks/functions/src/sdk/selection.test.ts index 2d711e4e..b3348fbb 100644 --- a/webhooks/functions/src/sdk/selection.test.ts +++ b/webhooks/functions/src/sdk/selection.test.ts @@ -198,18 +198,33 @@ describe(scene + ' handler', () => { const feed: Partial = { publications: [ { + openAccessLinks: [ + { + url: 'http://pub.url', + }, + ], title: 'first publication', baseUrl: '', authors: [], numberOfPages: 0, }, { + openAccessLinks: [ + { + url: 'http://pub.url', + }, + ], title: 'second publication', baseUrl: '', authors: [], numberOfPages: 0, }, { + openAccessLinks: [ + { + url: 'http://pub.url', + }, + ], title: 'third publication', baseUrl: '', authors: [], From ad2a2f711f0ad921f90e785882898a17e03be00d Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 17 Feb 2022 10:52:34 +0100 Subject: [PATCH 141/180] feat: home_user bookshelf --- sdk/custom/scenes/bookshelf.yaml | 2 -- sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 1 - webhooks/functions/src/constants.ts | 2 +- .../src/controller/handler/home_user.ts | 13 +++++++++++-- webhooks/functions/src/sdk/home_user.test.ts | 17 ++++++++++++++--- 5 files changed, 26 insertions(+), 9 deletions(-) delete mode 100644 sdk/custom/scenes/bookshelf.yaml diff --git a/sdk/custom/scenes/bookshelf.yaml b/sdk/custom/scenes/bookshelf.yaml deleted file mode 100644 index cddcd1bb..00000000 --- a/sdk/custom/scenes/bookshelf.yaml +++ /dev/null @@ -1,2 +0,0 @@ -onEnter: - webhookHandler: bookshelf__on_enter diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index 1c1584ba..cdf836ab 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -48,7 +48,6 @@ handlers: - name: home_user__intent__fallback_end - name: home_user__intent__silence - name: home_user__intent__silence_end -- name: bookshelf__on_enter - name: selection__on_enter - name: selection__intent__selects_book - name: selection__intent__repeat diff --git a/webhooks/functions/src/constants.ts b/webhooks/functions/src/constants.ts index c26a4b38..174495d5 100644 --- a/webhooks/functions/src/constants.ts +++ b/webhooks/functions/src/constants.ts @@ -4,7 +4,7 @@ export const NAME = "EDRLAB"; export const API_BASE_URL = "https://storage.googleapis.com/audiobook_edrlab/feed.json"; export const ALL_PUBLICATION_LIST_URL = "https://storage.googleapis.com/audiobook_edrlab/navigation/all.json"; -export const SELECTION_URL = 'https://storage.googleapis.com/audiobook_edrlab/groups/popular.json'; +export const BOOKSHELF_URL = 'https://storage.googleapis.com/audiobook_edrlab/groups/popular.json'; export const SEARCH_URL = 'https://europe-west1-audiobooks-a6348.cloudfunctions.net/indexer?url=https://storage.googleapis.com/audiobook_edrlab/navigation/all.json&query={query}'; export const THEMATIC_LIST_URL = 'https://storage.googleapis.com/audiobook_edrlab/navigation/thematic_list.json'; export const GENRE_LIST_URL = 'https://storage.googleapis.com/audiobook_edrlab/navigation/genre_list.json'; diff --git a/webhooks/functions/src/controller/handler/home_user.ts b/webhooks/functions/src/controller/handler/home_user.ts index d61f1a4f..e9529d96 100644 --- a/webhooks/functions/src/controller/handler/home_user.ts +++ b/webhooks/functions/src/controller/handler/home_user.ts @@ -1,4 +1,4 @@ -import { NAME } from "../../constants"; +import { BOOKSHELF_URL, GENRE_LIST_URL, NAME } from "../../constants"; import { THandlerFn } from "../../type"; import { Assistant } from "../Assistant"; import { missing } from "./void"; @@ -72,7 +72,16 @@ const collections: THandlerFn = (m) => { } const bookshelf: THandlerFn = (m) => { - m.nextScene = "bookshelf"; + + // @TODO + // init selection session in function + m.selectionSession.from = 'home_user__intent__bookshelf'; + m.selectionSession.kind = "PUBLICATION"; + m.selectionSession.nbChoice = 0; + m.selectionSession.nextUrlCounter = 0; + m.selectionSession.state = "RUNNING"; + m.selectionSession.url = BOOKSHELF_URL; + m.nextScene = "selection"; } const help: THandlerFn = (m) => { diff --git a/webhooks/functions/src/sdk/home_user.test.ts b/webhooks/functions/src/sdk/home_user.test.ts index 79b891aa..5f0ac866 100644 --- a/webhooks/functions/src/sdk/home_user.test.ts +++ b/webhooks/functions/src/sdk/home_user.test.ts @@ -1,9 +1,10 @@ -import {expressMocked, shell} from '../test/utils.test'; +import {expressMocked, shell, storageModelMocked} from '../test/utils.test'; import * as chai from 'chai'; // import * as sinon from 'sinon'; import {headers, body} from './conv.test'; import {parsedDataClone} from '../model/data.model.test'; import {IWebPubView} from 'opds-fetcher-parser/build/src/interface/webpub'; +import { BOOKSHELF_URL } from '../constants'; chai.should(); @@ -198,9 +199,19 @@ describe('home_user handler', () => { body.handler.name = 'home_user__intent__bookshelf'; body.scene.name = scene; - const data = await expressMocked(body, headers); + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + + model.data.store.session.scene.selection.from.should.to.be.eq('home_user__intent__bookshelf'); + model.data.store.session.scene.selection.kind.should.to.be.eq("PUBLICATION"); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); + model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(0); + model.data.store.session.scene.selection.state.should.to.be.eq("RUNNING"); + model.data.store.session.scene.selection.url.should.to.be.eq(BOOKSHELF_URL); - data.scene.next.name.should.to.be.eq('bookshelf'); + data.scene.next.name.should.to.be.eq('selection'); }); const help = `You can search for a specific book by title or author, browse our collections or check your bookshelf to start reading one of your preselected books.\nWhat would you like to do?\n`; From 7f139342b6a468be81330b642c0a660148df63cb Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 17 Feb 2022 10:58:13 +0100 Subject: [PATCH 142/180] chore: init selection session --- webhooks/functions/src/controller/Machine.ts | 24 ++++++++++++++++++- .../src/controller/handler/home_user.ts | 14 ++++------- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 986d6ad2..2070198c 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -1,7 +1,7 @@ import {ok} from 'assert'; import {AuthenticationStorage, http as httpOpdsFetcherParser, OpdsFetcher} from 'opds-fetcher-parser'; import {API_BASE_URL, LAST_SEEN_THRESHOLD, PADDING_GROUP, PADDING_PUB} from '../constants'; -import {TKeySessionScene, TStateAuthentication} from '../model/storage.interface'; +import {ISessionScene, TKeySessionScene, TKindSelection, TStateAuthentication} from '../model/storage.interface'; import {StorageModel} from '../model/storage.model'; import {i18n, TI18n, TI18nKey} from '../translation'; import {IConversationV3, TSdkScene2} from '../type'; @@ -10,6 +10,7 @@ import validator from 'validator'; import {Media} from '@assistant/conversation'; import {MediaType, OptionalMediaControl} from '@assistant/conversation/dist/api/schema'; import {IOpdsLinkView} from 'opds-fetcher-parser/build/src/interface/opds'; +import { TSdkHandler } from '../typings/sdkHandler'; export class Machine { private _conv: IConversationV3; @@ -160,12 +161,33 @@ export class Machine { ok(this._model); return this._model.store.session.scene.selection; } + + public set selectionSession(d: ISessionScene["selection"]) { + ok(this._model); + this._model.store.session.scene.selection = d; + } public get playerCurrent() { ok(this._model); return this._model.store.player.current; } + public initAndGoToSelectionSession({ + kind, from, url + }: { + kind: TKindSelection, + from: TSdkHandler, + url: string, + }) { + if (!this.isValidHttpUrl(url)) { + throw new Error("not a valid url"); + } + this.selectionSession = { + from, kind, url, nextUrlCounter: 0, state: "RUNNING", nbChoice: 0, + }; + this.nextScene = "selection"; + } + public async selectGroup(url: string, number: number) { ok(this._model); if (!this.isValidHttpUrl(url)) { diff --git a/webhooks/functions/src/controller/handler/home_user.ts b/webhooks/functions/src/controller/handler/home_user.ts index e9529d96..2b8b639d 100644 --- a/webhooks/functions/src/controller/handler/home_user.ts +++ b/webhooks/functions/src/controller/handler/home_user.ts @@ -73,15 +73,11 @@ const collections: THandlerFn = (m) => { const bookshelf: THandlerFn = (m) => { - // @TODO - // init selection session in function - m.selectionSession.from = 'home_user__intent__bookshelf'; - m.selectionSession.kind = "PUBLICATION"; - m.selectionSession.nbChoice = 0; - m.selectionSession.nextUrlCounter = 0; - m.selectionSession.state = "RUNNING"; - m.selectionSession.url = BOOKSHELF_URL; - m.nextScene = "selection"; + m.initAndGoToSelectionSession({ + kind: 'PUBLICATION', + from: "home_user__intent__bookshelf", + url: BOOKSHELF_URL, + }); } const help: THandlerFn = (m) => { From d0f4cce08b1303ac26432bc91cb1891f0435a1e6 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 17 Feb 2022 10:58:36 +0100 Subject: [PATCH 143/180] chore: lint --- webhooks/functions/src/controller/Machine.ts | 34 ++++++++++---------- webhooks/functions/src/sdk/home_user.test.ts | 6 ++-- webhooks/functions/src/sdk/selection.test.ts | 32 +++++++++--------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 2070198c..8295229e 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -10,7 +10,7 @@ import validator from 'validator'; import {Media} from '@assistant/conversation'; import {MediaType, OptionalMediaControl} from '@assistant/conversation/dist/api/schema'; import {IOpdsLinkView} from 'opds-fetcher-parser/build/src/interface/opds'; -import { TSdkHandler } from '../typings/sdkHandler'; +import {TSdkHandler} from '../typings/sdkHandler'; export class Machine { private _conv: IConversationV3; @@ -161,8 +161,8 @@ export class Machine { ok(this._model); return this._model.store.session.scene.selection; } - - public set selectionSession(d: ISessionScene["selection"]) { + + public set selectionSession(d: ISessionScene['selection']) { ok(this._model); this._model.store.session.scene.selection = d; } @@ -173,37 +173,37 @@ export class Machine { } public initAndGoToSelectionSession({ - kind, from, url + kind, from, url, }: { kind: TKindSelection, from: TSdkHandler, url: string, }) { if (!this.isValidHttpUrl(url)) { - throw new Error("not a valid url"); + throw new Error('not a valid url'); } this.selectionSession = { - from, kind, url, nextUrlCounter: 0, state: "RUNNING", nbChoice: 0, + from, kind, url, nextUrlCounter: 0, state: 'RUNNING', nbChoice: 0, }; - this.nextScene = "selection"; + this.nextScene = 'selection'; } public async selectGroup(url: string, number: number) { ok(this._model); if (!this.isValidHttpUrl(url)) { - throw new Error("url not valid"); + throw new Error('url not valid'); } - + const group = await this.getGroupFromNumberInSelectionWithUrl(url, number); if (group) { const groupUrl = group.groupUrl; if (!this.isValidHttpUrl(groupUrl)) { - throw new Error("group url not valid"); + throw new Error('group url not valid'); } this.selectionSession.url = group.groupUrl; - this.selectionSession.kind = "PUBLICATION"; // set to publication mode + this.selectionSession.kind = 'PUBLICATION'; // set to publication mode this.selectionSession.nextUrlCounter = 0; // reset - this.selectionSession.state = "RUNNING"; + this.selectionSession.state = 'RUNNING'; return true; } @@ -213,14 +213,14 @@ export class Machine { public async selectPublication(url: string, number: number) { ok(this._model); if (!this.isValidHttpUrl(url)) { - throw new Error("url not valid"); + throw new Error('url not valid'); } - + const pub = await this.getPublicationFromNumberInSelectionWithUrl(url, number); if (pub) { const webpubUrl = pub.webpubUrl; if (!this.isValidHttpUrl(webpubUrl)) { - throw new Error("webpub url not valid"); + throw new Error('webpub url not valid'); } this.initPlayerCurrentWithWebpubUrl(pub.webpubUrl); @@ -239,7 +239,7 @@ export class Machine { } public async getPublicationFromNumberInSelectionWithUrl(url: string, number: number) { - const {publication} = await this.getPublicationFromFeed(url); + const {publication} = await this.getPublicationFromFeed(url); const pub = publication[number - 1]; if (pub) { @@ -249,7 +249,7 @@ export class Machine { } public async getGroupFromNumberInSelectionWithUrl(url: string, number: number) { - const {groups} = await this.getGroupsFromFeed(url); + const {groups} = await this.getGroupsFromFeed(url); const group = groups[number - 1]; if (group) { diff --git a/webhooks/functions/src/sdk/home_user.test.ts b/webhooks/functions/src/sdk/home_user.test.ts index 5f0ac866..1b8ffc73 100644 --- a/webhooks/functions/src/sdk/home_user.test.ts +++ b/webhooks/functions/src/sdk/home_user.test.ts @@ -4,7 +4,7 @@ import * as chai from 'chai'; import {headers, body} from './conv.test'; import {parsedDataClone} from '../model/data.model.test'; import {IWebPubView} from 'opds-fetcher-parser/build/src/interface/webpub'; -import { BOOKSHELF_URL } from '../constants'; +import {BOOKSHELF_URL} from '../constants'; chai.should(); @@ -205,10 +205,10 @@ describe('home_user handler', () => { const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); model.data.store.session.scene.selection.from.should.to.be.eq('home_user__intent__bookshelf'); - model.data.store.session.scene.selection.kind.should.to.be.eq("PUBLICATION"); + model.data.store.session.scene.selection.kind.should.to.be.eq('PUBLICATION'); model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(0); - model.data.store.session.scene.selection.state.should.to.be.eq("RUNNING"); + model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); model.data.store.session.scene.selection.url.should.to.be.eq(BOOKSHELF_URL); data.scene.next.name.should.to.be.eq('selection'); diff --git a/webhooks/functions/src/sdk/selection.test.ts b/webhooks/functions/src/sdk/selection.test.ts index b3348fbb..5602d44d 100644 --- a/webhooks/functions/src/sdk/selection.test.ts +++ b/webhooks/functions/src/sdk/selection.test.ts @@ -60,7 +60,7 @@ describe(scene + ' handler', () => { return a + b + c; }; - const help = `Pick one out of 3 titles by mentioning their numbers. You can also ask for 'another one'.\n` // What would you like to do?\n`; + const help = `Pick one out of 3 titles by mentioning their numbers. You can also ask for 'another one'.\n`; // What would you like to do?\n`; describe('app', () => { it('on enter', async () => { @@ -198,33 +198,33 @@ describe(scene + ' handler', () => { const feed: Partial = { publications: [ { - openAccessLinks: [ - { - url: 'http://pub.url', - }, - ], + openAccessLinks: [ + { + url: 'http://pub.url', + }, + ], title: 'first publication', baseUrl: '', authors: [], numberOfPages: 0, }, { - openAccessLinks: [ - { - url: 'http://pub.url', - }, - ], + openAccessLinks: [ + { + url: 'http://pub.url', + }, + ], title: 'second publication', baseUrl: '', authors: [], numberOfPages: 0, }, { - openAccessLinks: [ - { - url: 'http://pub.url', - }, - ], + openAccessLinks: [ + { + url: 'http://pub.url', + }, + ], title: 'third publication', baseUrl: '', authors: [], From 4d6520ea4f67d69a345a2d4b1d770a8c67f839c4 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 17 Feb 2022 16:20:23 +0100 Subject: [PATCH 144/180] feat: search scene --- sdk/custom/intents/en/search.yaml | 12 ++++++++++++ sdk/custom/intents/en/search_query.yaml | 4 ++++ sdk/custom/intents/search.yaml | 5 ++++- sdk/custom/intents/search_query.yaml | 4 ++++ sdk/custom/scenes/search.yaml | 10 +++++++++- sdk/custom/types/en/string.yaml | 1 + sdk/custom/types/string.yaml | 1 + sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 3 +++ 8 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 sdk/custom/intents/en/search.yaml create mode 100644 sdk/custom/intents/en/search_query.yaml create mode 100644 sdk/custom/intents/search_query.yaml create mode 100644 sdk/custom/types/en/string.yaml create mode 100644 sdk/custom/types/string.yaml diff --git a/sdk/custom/intents/en/search.yaml b/sdk/custom/intents/en/search.yaml new file mode 100644 index 00000000..18bdbbcf --- /dev/null +++ b/sdk/custom/intents/en/search.yaml @@ -0,0 +1,12 @@ +trainingPhrases: +- I am looking for a book ($query 'The Little Prince by Antoine de Saint-Exupéry' + auto=false) +- I want to listen ($query 'this book title' auto=false) +- I want to listen ($query 'this book by this author name' auto=false) +- search ($query 'Wild by Cheryl Strayed' auto=false) +- I want to search ($query 'The Little Prince by Antoine de Saint-Exupéry' auto=false) +- I am looking for a book by ($query 'author' auto=false) +- I want to search a book +- search a title +- search a book +- search diff --git a/sdk/custom/intents/en/search_query.yaml b/sdk/custom/intents/en/search_query.yaml new file mode 100644 index 00000000..a0564f23 --- /dev/null +++ b/sdk/custom/intents/en/search_query.yaml @@ -0,0 +1,4 @@ +trainingPhrases: +- ($query 'To kill a mockingbird by Harper Lee' auto=false) +- ($query 'Wild by Cheryl Strayed' auto=false) +- ($query 'The Little Prince by Antoine de Saint-Exupéry' auto=false) diff --git a/sdk/custom/intents/search.yaml b/sdk/custom/intents/search.yaml index 0967ef42..4453fe05 100644 --- a/sdk/custom/intents/search.yaml +++ b/sdk/custom/intents/search.yaml @@ -1 +1,4 @@ -{} +parameters: +- name: query + type: + name: string diff --git a/sdk/custom/intents/search_query.yaml b/sdk/custom/intents/search_query.yaml new file mode 100644 index 00000000..4453fe05 --- /dev/null +++ b/sdk/custom/intents/search_query.yaml @@ -0,0 +1,4 @@ +parameters: +- name: query + type: + name: string diff --git a/sdk/custom/scenes/search.yaml b/sdk/custom/scenes/search.yaml index 0967ef42..651363f0 100644 --- a/sdk/custom/scenes/search.yaml +++ b/sdk/custom/scenes/search.yaml @@ -1 +1,9 @@ -{} +intentEvents: +- handler: + webhookHandler: search__intent__search_query + intent: search_query +- handler: + webhookHandler: search__intent__search + intent: search +onEnter: + webhookHandler: search__on_enter diff --git a/sdk/custom/types/en/string.yaml b/sdk/custom/types/en/string.yaml new file mode 100644 index 00000000..63ddd907 --- /dev/null +++ b/sdk/custom/types/en/string.yaml @@ -0,0 +1 @@ +freeText: {} diff --git a/sdk/custom/types/string.yaml b/sdk/custom/types/string.yaml new file mode 100644 index 00000000..63ddd907 --- /dev/null +++ b/sdk/custom/types/string.yaml @@ -0,0 +1 @@ +freeText: {} diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index cdf836ab..7a494a20 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -68,6 +68,9 @@ handlers: - name: player__intent__media_status_paused - name: player__intent__media_status_stopped - name: player__intent__media_status_failed +- name: search__on_enter +- name: search__intent__search_query +- name: search__intent__search httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 From 132ed41639bc027017c9d7588b2449149be608e5 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 17 Feb 2022 16:21:10 +0100 Subject: [PATCH 145/180] feat: search scene --- webhooks/functions/src/constants.ts | 1 + .../functions/src/controller/Assistant.ts | 4 + webhooks/functions/src/controller/Machine.ts | 28 +++- .../functions/src/controller/handler/index.ts | 2 + .../src/controller/handler/search.ts | 54 +++++++ .../src/controller/handler/selection.ts | 7 +- .../functions/src/model/data.model.test.ts | 8 + webhooks/functions/src/model/storage.dto.ts | 4 + .../functions/src/model/storage.interface.ts | 5 + webhooks/functions/src/sdk/search.test.ts | 143 ++++++++++++++++++ webhooks/functions/src/translation/en/en.json | 2 +- .../functions/src/typings/sdkHandler.d.ts | 2 +- webhooks/functions/src/typings/sdkScene.d.ts | 2 +- 13 files changed, 257 insertions(+), 5 deletions(-) create mode 100644 webhooks/functions/src/controller/handler/search.ts create mode 100644 webhooks/functions/src/sdk/search.test.ts diff --git a/webhooks/functions/src/constants.ts b/webhooks/functions/src/constants.ts index 174495d5..2d1f95a5 100644 --- a/webhooks/functions/src/constants.ts +++ b/webhooks/functions/src/constants.ts @@ -6,6 +6,7 @@ export const API_BASE_URL = "https://storage.googleapis.com/audiobook_edrlab/fee export const ALL_PUBLICATION_LIST_URL = "https://storage.googleapis.com/audiobook_edrlab/navigation/all.json"; export const BOOKSHELF_URL = 'https://storage.googleapis.com/audiobook_edrlab/groups/popular.json'; export const SEARCH_URL = 'https://europe-west1-audiobooks-a6348.cloudfunctions.net/indexer?url=https://storage.googleapis.com/audiobook_edrlab/navigation/all.json&query={query}'; +export const SEARCH_URL_FN = (value: string) => SEARCH_URL.replace("{query}", value); export const THEMATIC_LIST_URL = 'https://storage.googleapis.com/audiobook_edrlab/navigation/thematic_list.json'; export const GENRE_LIST_URL = 'https://storage.googleapis.com/audiobook_edrlab/navigation/genre_list.json'; export const DEFAULT_LANGUAGE: TDefaultLanguage = 'en'; diff --git a/webhooks/functions/src/controller/Assistant.ts b/webhooks/functions/src/controller/Assistant.ts index 93434baa..3c518c90 100644 --- a/webhooks/functions/src/controller/Assistant.ts +++ b/webhooks/functions/src/controller/Assistant.ts @@ -32,6 +32,10 @@ export class Assistant { // @TODO fix translation conv.add('Oops, something went wrong. I will exit the app. Feel free to reopen it as soon as possible.'); + + // @TODO + // remove session + // and return to main menu or home_user if authenticated }); if (storageModel) { diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 8295229e..fda0f213 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -167,6 +167,16 @@ export class Machine { this._model.store.session.scene.selection = d; } + public get searchSession() { + ok(this._model); + return this._model.store.session.scene.search; + } + + public set searchSession(d: ISessionScene['search']) { + ok(this._model); + this._model.store.session.scene.search = d; + } + public get playerCurrent() { ok(this._model); return this._model.store.player.current; @@ -259,7 +269,19 @@ export class Machine { } public get selectBookNumber() { - return this._conv.intent.params?.number.resolved as number | undefined; + const v = this._conv.intent.params?.number.resolved; + if (v && typeof v === 'number') { + return v; + } + return undefined; + } + + public get querySearch() { + const v = this._conv.intent.params?.query.resolved; + if (v && typeof v === 'string') { + return v; + } + return undefined; } public async getNexLinkPublicationWithUrl(url: string) { @@ -485,6 +507,10 @@ export class Machine { state: 'DEFAULT', }, 'selection': resetSelection(), + 'search': { + state: 'DEFAULT', + query: '', + }, }, }; this._model.store.user.sessionId = id; diff --git a/webhooks/functions/src/controller/handler/index.ts b/webhooks/functions/src/controller/handler/index.ts index 221a4b3a..8fc941e8 100644 --- a/webhooks/functions/src/controller/handler/index.ts +++ b/webhooks/functions/src/controller/handler/index.ts @@ -6,6 +6,7 @@ import { home_user } from "./home_user"; import { info } from "./info"; import { main } from "./main"; import { player } from "./player"; +import { search } from "./search"; import { selection } from "./selection"; export const handler = (app = new Assistant({})) => { @@ -47,4 +48,5 @@ export const handler = (app = new Assistant({})) => { info(app); selection(app); player(app); + search(app); } diff --git a/webhooks/functions/src/controller/handler/search.ts b/webhooks/functions/src/controller/handler/search.ts new file mode 100644 index 00000000..eae2f0c4 --- /dev/null +++ b/webhooks/functions/src/controller/handler/search.ts @@ -0,0 +1,54 @@ +import { SEARCH_URL_FN } from "../../constants"; +import { THandlerFn } from "../../type"; +import { Assistant } from "../Assistant"; + +export const search = (app: Assistant) => { + + app.handle("search__on_enter", enter); + app.handle("search__intent__search", query); + app.handle("search__intent__search_query", query); +} + +const enter: THandlerFn = (m) => { + + const { state, query } = m.searchSession; + + if (state === "RUNNING") { + m.say('search.enter.1'); + // wait intent search query + + } else if (state === "FINISH") { + + if (!query) { + m.nextScene = "search"; + return ; + } + + m.initAndGoToSelectionSession({ + kind: 'PUBLICATION', + url: SEARCH_URL_FN(encodeURIComponent(query)), // @todo do you have to encode Url ? + from: 'search__on_enter', + }); + + } else { + throw new Error("invalid search state"); + } +} + +const query: THandlerFn = (m) => { + + const query = m.querySearch; + if (!query) { + m.searchSession = { + query: '', + state: "RUNNING", + } + } else { + m.searchSession = { + query, + state: "FINISH", + } + } + + m.nextScene = "search"; +} diff --git a/webhooks/functions/src/controller/handler/selection.ts b/webhooks/functions/src/controller/handler/selection.ts index 2a02eb03..370e03cd 100644 --- a/webhooks/functions/src/controller/handler/selection.ts +++ b/webhooks/functions/src/controller/handler/selection.ts @@ -31,6 +31,11 @@ const enter: THandlerFn = async (m) => { return ; } + // @TODO + // handle only one group or publication + // redirect to nextScene 'selection' for group + // or 'player-prequel' for a publication + const handler = m.selectionSession.from; // intro if (handler === "home_user__intent__bookshelf") { @@ -90,7 +95,7 @@ const enter: THandlerFn = async (m) => { // reset selection session // move to home user } - m.nextScene = "selection"; + // m.nextScene = "selection"; } diff --git a/webhooks/functions/src/model/data.model.test.ts b/webhooks/functions/src/model/data.model.test.ts index 9a2ef73b..96c77e2d 100644 --- a/webhooks/functions/src/model/data.model.test.ts +++ b/webhooks/functions/src/model/data.model.test.ts @@ -24,6 +24,10 @@ export const freshDataClone = () => Object.assign({ nbChoice: 0, from: 'main', }, + search: { + state: 'DEFAULT', + query: '', + }, }, }, user: { @@ -53,6 +57,10 @@ export const parsedDataClone = (): IStorage => Object.assign({ from: 'main', nbChoice: 0, }, + search: { + state: 'DEFAULT', + query: '', + }, }, }, user: { diff --git a/webhooks/functions/src/model/storage.dto.ts b/webhooks/functions/src/model/storage.dto.ts index 8a1fe407..288bd4de 100644 --- a/webhooks/functions/src/model/storage.dto.ts +++ b/webhooks/functions/src/model/storage.dto.ts @@ -95,6 +95,10 @@ class StorageSessionDto implements IStorageSession { state: 'DEFAULT', }, 'selection': resetSelection(), + 'search': { + state: 'DEFAULT', + query: '', + }, }; } } diff --git a/webhooks/functions/src/model/storage.interface.ts b/webhooks/functions/src/model/storage.interface.ts index c2554c28..e2a0d2cd 100644 --- a/webhooks/functions/src/model/storage.interface.ts +++ b/webhooks/functions/src/model/storage.interface.ts @@ -23,6 +23,7 @@ export type TStateAuthentication = 'NO_LINKED' | 'NEWLY_LINKED' | 'LINKED' | TSt export type TStateHomeUser = 'SESSION' | TStateDefault; export type TStateSelection = 'RUNNING' | 'FINISH' | TStateDefault; export type TKindSelection = 'PUBLICATION' | 'GROUP'; +export type TStateSearch = 'RUNNING' | 'FINISH' | TStateDefault; export interface ISessionScene { 'home_user': { @@ -35,6 +36,10 @@ export interface ISessionScene { nextUrlCounter: number, from: TSdkHandler, nbChoice: number, + }, + 'search': { + state: TStateSearch, + query: string, } } export type TKeySessionScene = keyof ISessionScene; diff --git a/webhooks/functions/src/sdk/search.test.ts b/webhooks/functions/src/sdk/search.test.ts new file mode 100644 index 00000000..8cb1a1cd --- /dev/null +++ b/webhooks/functions/src/sdk/search.test.ts @@ -0,0 +1,143 @@ +import {expressMocked, shell, storageModelMocked} from '../test/utils.test'; +import * as chai from 'chai'; +// import * as sinon from 'sinon'; +import {headers, body} from './conv.test'; +import {parsedDataClone} from '../model/data.model.test'; +import {SEARCH_URL_FN} from '../constants'; + + +chai.should(); + +const scene = 'search'; + +const yaml = `intentEvents: +- handler: + webhookHandler: search__intent__search_query + intent: search_query +- handler: + webhookHandler: search__intent__search + intent: search +onEnter: + webhookHandler: search__on_enter +`; + +describe(scene + ' handler', () => { + describe('sdk', () => { + it('check main scene', (done) => { + shell(`cat custom/scenes/${scene}.yaml`, (stdout) => { + stdout.should.to.be.eq(yaml); + }, done); + }); + }); + + describe('app', () => { + it('on enter default state', async () => { + body.handler.name = 'search__on_enter'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + + pullData.session.scene.search.query = ''; + pullData.session.scene.search.state = 'DEFAULT'; + + const message = `Oops, something went wrong. I will exit the app. Feel free to reopen it as soon as possible.`; + + const model = await storageModelMocked(pullData); + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + data.scene.next.name.should.to.be.eq('actions.scene.END_CONVERSATION'); + }); + it('on enter no query available and running', async () => { + body.handler.name = 'search__on_enter'; + body.scene.name = scene; + + const message = `What book or author are you looking for ?\n`; + + const pullData = parsedDataClone(); + + pullData.session.scene.search.query = ''; + pullData.session.scene.search.state = 'RUNNING'; + + const model = await storageModelMocked(pullData); + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + }); + it('on enter query and finish state', async () => { + body.handler.name = 'search__on_enter'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + + pullData.session.scene.search.query = 'my query'; + pullData.session.scene.search.state = 'FINISH'; + + const model = await storageModelMocked(pullData); + + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + + model.data.store.session.scene.selection.from.should.to.be.eq('search__on_enter'); + model.data.store.session.scene.selection.kind.should.to.be.eq('PUBLICATION'); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); + model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(0); + model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); + model.data.store.session.scene.selection.url.should.to.be.eq(SEARCH_URL_FN('my%20query')); // @TODO check url encoding + + // request url with query + // and set nextScene to selections + + data.scene.next.name.should.to.be.eq('selection'); + }); + it('search', async () => { + body.handler.name = 'search__intent__search'; + body.scene.name = scene; + body.intent.params = { + query: { + original: 'my query', + resolved: 'my query', + }, + }; + + // parse query and state = FINISH + + const pullData = parsedDataClone(); + + pullData.session.scene.search.query = ''; + pullData.session.scene.search.state = 'RUNNING'; + + const model = await storageModelMocked(pullData); + + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + + model.data.store.session.scene.search.state.should.to.be.eq('FINISH'); + model.data.store.session.scene.search.query.should.to.be.eq('my query'); + data.scene.next.name.should.to.be.eq('search'); + }); + it('query search', async () => { + body.handler.name = 'search__intent__search_query'; + body.scene.name = scene; + body.intent.params = { + query: { + original: 'my query', + resolved: 'my query', + }, + }; + + // parse query and state = FINISH + + const pullData = parsedDataClone(); + + pullData.session.scene.search.query = ''; + pullData.session.scene.search.state = 'RUNNING'; + + const model = await storageModelMocked(pullData); + + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + + model.data.store.session.scene.search.state.should.to.be.eq('FINISH'); + model.data.store.session.scene.search.query.should.to.be.eq('my query'); + data.scene.next.name.should.to.be.eq('search'); + }); + }); +}); diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index cc6792e2..eab1c6e0 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -72,7 +72,7 @@ }, "search": { "enter": { - "1": "Sure thing! What book or author are you looking for ?" + "1": "What book or author are you looking for ?" } }, "selection": { diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index 11b03c96..cd248c7c 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'bookshelf__on_enter' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end' | 'player__on_enter' | 'player__intent__media_status_finished' | 'player__intent__media_status_paused' | 'player__intent__media_status_stopped' | 'player__intent__media_status_failed'; +export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end' | 'player__on_enter' | 'player__intent__media_status_finished' | 'player__intent__media_status_paused' | 'player__intent__media_status_stopped' | 'player__intent__media_status_failed' | 'search__on_enter' | 'search__intent__search_query' | 'search__intent__search'; diff --git a/webhooks/functions/src/typings/sdkScene.d.ts b/webhooks/functions/src/typings/sdkScene.d.ts index 6e37cd58..0b4e5ad9 100644 --- a/webhooks/functions/src/typings/sdkScene.d.ts +++ b/webhooks/functions/src/typings/sdkScene.d.ts @@ -1,4 +1,4 @@ // npm run scene-typed ; -export type TSdkScene = 'bookshelf' | 'collections' | 'home_new_user' | 'home_new_user_AccountLinking' | 'home_new_user_maybe_later' | 'home_new_user_no' | 'home_user' | 'info' | 'player' | 'search' | 'selection'; +export type TSdkScene = 'collections' | 'home_new_user' | 'home_new_user_AccountLinking' | 'home_new_user_maybe_later' | 'home_new_user_no' | 'home_user' | 'info' | 'player' | 'search' | 'selection'; From 8f5f518b94bc69c67aa11db11c85a3337b3bc6d0 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 17 Feb 2022 17:01:31 +0100 Subject: [PATCH 146/180] feat: collections --- sdk/custom/intents/by_genre.yaml | 1 + sdk/custom/intents/by_theme.yaml | 1 + sdk/custom/intents/en/by_genre.yaml | 6 + sdk/custom/intents/en/by_theme.yaml | 6 + sdk/custom/scenes/collections.yaml | 34 +++- sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 9 + .../src/controller/handler/collections.ts | 56 ++++++ .../functions/src/controller/handler/index.ts | 2 + .../functions/src/sdk/collections.test.ts | 182 ++++++++++++++++++ webhooks/functions/src/translation/en/en.json | 8 + webhooks/functions/src/typings/i18n.d.ts | 4 +- .../functions/src/typings/sdkHandler.d.ts | 2 +- 12 files changed, 307 insertions(+), 4 deletions(-) create mode 100644 sdk/custom/intents/by_genre.yaml create mode 100644 sdk/custom/intents/by_theme.yaml create mode 100644 sdk/custom/intents/en/by_genre.yaml create mode 100644 sdk/custom/intents/en/by_theme.yaml create mode 100644 webhooks/functions/src/controller/handler/collections.ts create mode 100644 webhooks/functions/src/sdk/collections.test.ts diff --git a/sdk/custom/intents/by_genre.yaml b/sdk/custom/intents/by_genre.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/sdk/custom/intents/by_genre.yaml @@ -0,0 +1 @@ +{} diff --git a/sdk/custom/intents/by_theme.yaml b/sdk/custom/intents/by_theme.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/sdk/custom/intents/by_theme.yaml @@ -0,0 +1 @@ +{} diff --git a/sdk/custom/intents/en/by_genre.yaml b/sdk/custom/intents/en/by_genre.yaml new file mode 100644 index 00000000..e1c6f812 --- /dev/null +++ b/sdk/custom/intents/en/by_genre.yaml @@ -0,0 +1,6 @@ +trainingPhrases: +- by genre please +- genre +- I prefer by genre +- I prefer to get a book selection by genre +- by genre diff --git a/sdk/custom/intents/en/by_theme.yaml b/sdk/custom/intents/en/by_theme.yaml new file mode 100644 index 00000000..8447be17 --- /dev/null +++ b/sdk/custom/intents/en/by_theme.yaml @@ -0,0 +1,6 @@ +trainingPhrases: +- by theme please +- theme +- I prefer by theme +- I prefer to get a book selection by theme +- by theme diff --git a/sdk/custom/scenes/collections.yaml b/sdk/custom/scenes/collections.yaml index 0967ef42..83d250a4 100644 --- a/sdk/custom/scenes/collections.yaml +++ b/sdk/custom/scenes/collections.yaml @@ -1 +1,33 @@ -{} +intentEvents: +- handler: + webhookHandler: collections__intent__bookshelf + intent: bookshelf +- handler: + webhookHandler: collections__intent__by_genre + intent: by_genre +- handler: + webhookHandler: collections__intent__by_theme + intent: by_theme +- handler: + webhookHandler: collections__intent__help + intent: help +- handler: + webhookHandler: collections__intent__fallback + intent: actions.intent.NO_MATCH_1 +- handler: + webhookHandler: collections__intent__fallback + intent: actions.intent.NO_MATCH_2 +- handler: + webhookHandler: collections__intent__fallback_end + intent: actions.intent.NO_MATCH_FINAL +- handler: + webhookHandler: collections__intent__silence + intent: actions.intent.NO_INPUT_1 +- handler: + webhookHandler: collections__intent__silence + intent: actions.intent.NO_INPUT_2 +- handler: + webhookHandler: collections__intent__silence_end + intent: actions.intent.NO_INPUT_FINAL +onEnter: + webhookHandler: collections__on_enter diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index 7a494a20..b3220156 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -71,6 +71,15 @@ handlers: - name: search__on_enter - name: search__intent__search_query - name: search__intent__search +- name: collections__on_enter +- name: collections__intent__bookshelf +- name: collections__intent__by_genre +- name: collections__intent__by_theme +- name: collections__intent__help +- name: collections__intent__fallback +- name: collections__intent__fallback_end +- name: collections__intent__silence +- name: collections__intent__silence_end httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/controller/handler/collections.ts b/webhooks/functions/src/controller/handler/collections.ts new file mode 100644 index 00000000..cd943459 --- /dev/null +++ b/webhooks/functions/src/controller/handler/collections.ts @@ -0,0 +1,56 @@ +import { BOOKSHELF_URL, GENRE_LIST_URL, NAME, THEMATIC_LIST_URL } from "../../constants"; +import { THandlerFn } from "../../type"; +import { Assistant } from "../Assistant"; +import { missing } from "./void"; + +export const collections = (app: Assistant) => { + + app.handle("collections__on_enter", enter); + app.handle("collections__intent__bookshelf", bookshelf); + app.handle("collections__intent__by_genre", genre); + app.handle("collections__intent__by_theme", theme); + app.handle("collections__intent__fallback", help); + app.handle("collections__intent__fallback_end", missing); + app.handle("collections__intent__help", help); + app.handle("collections__intent__silence", help); + app.handle("collections__intent__silence_end", missing); + +} + +const enter: THandlerFn = (m) => { + m.say('collections.enter.1'); +} + +const bookshelf: THandlerFn = (m) => { + + m.initAndGoToSelectionSession({ + kind: 'PUBLICATION', + url: BOOKSHELF_URL, + from: 'collections__intent__bookshelf', + }); +} + +const genre: THandlerFn = (m) => { + + m.initAndGoToSelectionSession({ + kind: 'GROUP', + url: GENRE_LIST_URL, + from: 'collections__intent__by_genre', + }); +} + +const theme: THandlerFn = (m) => { + + m.initAndGoToSelectionSession({ + kind: 'GROUP', + url: THEMATIC_LIST_URL, + from: 'collections__intent__by_theme', + }); +} + +const help: THandlerFn = (m) => { + + m.say('collections.help.1'); + + m.nextScene = "collections"; +} diff --git a/webhooks/functions/src/controller/handler/index.ts b/webhooks/functions/src/controller/handler/index.ts index 8fc941e8..64a37c08 100644 --- a/webhooks/functions/src/controller/handler/index.ts +++ b/webhooks/functions/src/controller/handler/index.ts @@ -1,4 +1,5 @@ import { Assistant } from "../Assistant"; +import { collections } from "./collections"; import { home_new_user } from "./home_new_user"; import { home_new_user_maybe_later } from "./home_new_user_maybe_later"; import { home_new_user_no } from "./home_new_user_no"; @@ -49,4 +50,5 @@ export const handler = (app = new Assistant({})) => { selection(app); player(app); search(app); + collections(app); } diff --git a/webhooks/functions/src/sdk/collections.test.ts b/webhooks/functions/src/sdk/collections.test.ts new file mode 100644 index 00000000..4880c321 --- /dev/null +++ b/webhooks/functions/src/sdk/collections.test.ts @@ -0,0 +1,182 @@ +import {expressMocked, shell, storageModelMocked} from '../test/utils.test'; +import * as chai from 'chai'; +// import * as sinon from 'sinon'; +import {headers, body} from './conv.test'; +import {parsedDataClone} from '../model/data.model.test'; +import {BOOKSHELF_URL, GENRE_LIST_URL, THEMATIC_LIST_URL} from '../constants'; + + +chai.should(); + +const scene = 'collections'; + +const yaml = `intentEvents: +- handler: + webhookHandler: collections__intent__bookshelf + intent: bookshelf +- handler: + webhookHandler: collections__intent__by_genre + intent: by_genre +- handler: + webhookHandler: collections__intent__by_theme + intent: by_theme +- handler: + webhookHandler: collections__intent__help + intent: help +- handler: + webhookHandler: collections__intent__fallback + intent: actions.intent.NO_MATCH_1 +- handler: + webhookHandler: collections__intent__fallback + intent: actions.intent.NO_MATCH_2 +- handler: + webhookHandler: collections__intent__fallback_end + intent: actions.intent.NO_MATCH_FINAL +- handler: + webhookHandler: collections__intent__silence + intent: actions.intent.NO_INPUT_1 +- handler: + webhookHandler: collections__intent__silence + intent: actions.intent.NO_INPUT_2 +- handler: + webhookHandler: collections__intent__silence_end + intent: actions.intent.NO_INPUT_FINAL +onEnter: + webhookHandler: collections__on_enter +`; + +describe(scene + ' handler', () => { + describe('sdk', () => { + it('check main scene', (done) => { + shell(`cat custom/scenes/${scene}.yaml`, (stdout) => { + stdout.should.to.be.eq(yaml); + }, done); + }); + }); + + describe('app', () => { + it('on enter', async () => { + body.handler.name = 'collections__on_enter'; + body.scene.name = scene; + + const message = `Okay, would you prefer to get a book selection by theme or by genre ?\n`; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + }); + + it('by genre', async () => { + body.handler.name = 'collections__intent__by_genre'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + + model.data.store.session.scene.selection.from.should.to.be.eq('collections__intent__by_genre'); + model.data.store.session.scene.selection.kind.should.to.be.eq('GROUP'); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); + model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(0); + model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); + model.data.store.session.scene.selection.url.should.to.be.eq(GENRE_LIST_URL); + + data.scene.next.name.should.to.be.eq('selection'); + }); + it('by theme', async () => { + body.handler.name = 'collections__intent__by_theme'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + + model.data.store.session.scene.selection.from.should.to.be.eq('collections__intent__by_theme'); + model.data.store.session.scene.selection.kind.should.to.be.eq('GROUP'); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); + model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(0); + model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); + model.data.store.session.scene.selection.url.should.to.be.eq(THEMATIC_LIST_URL); + + data.scene.next.name.should.to.be.eq('selection'); + }); + it('bookshelf', async () => { + body.handler.name = 'collections__intent__bookshelf'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + + model.data.store.session.scene.selection.from.should.to.be.eq('collections__intent__bookshelf'); + model.data.store.session.scene.selection.kind.should.to.be.eq('PUBLICATION'); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); + model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(0); + model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); + model.data.store.session.scene.selection.url.should.to.be.eq(BOOKSHELF_URL); + + data.scene.next.name.should.to.be.eq('selection'); + }); + + const help = `To hear an overview of available themes, say 'theme'. For an overview of available genres, say 'genre'. Do you want to hear a list of available themes or genres ?\n`; + + it('help', async () => { + body.handler.name = 'collections__intent__help'; + body.scene.name = scene; + + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('collections'); + }); + + it('fallback 1 and 2', async () => { + body.handler.name = 'collections__intent__help'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('collections'); + }); + + it('fallback 3', async () => { + body.handler.name = 'collections__intent__fallback_end'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + + // data.scene.next.name.should.to.be.eq('home_new_user'); + }); + + it('silence 1 and 2', async () => { + body.handler.name = 'collections__intent__silence'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq(help); + + data.scene.next.name.should.to.be.eq('collections'); + }); + + it('silence 3', async () => { + body.handler.name = 'collections__intent__fallback_end'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + + // data.scene.next.name.should.to.be.eq('home_new_user'); + }); + }); +}); diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index eab1c6e0..78cb5153 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -108,6 +108,14 @@ "player": { "start": "I start reading {{- title}}" }, + "collections": { + "enter": { + "1": "Okay, would you prefer to get a book selection by theme or by genre ?" + }, + "help": { + "1": "To hear an overview of available themes, say 'theme'. For an overview of available genres, say 'genre'. Do you want to hear a list of available themes or genres ?" + } + }, "void": "need to replace this message", "bye": { "1": "Thank you for trying the app. To pick up your reading again, come back any time" diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index beea4c76..5c287b20 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "player.start" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", + "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "player.start" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:player.start" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", + "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:player.start" | "en:collections.enter.1" | "en:collections.help.1" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index cd248c7c..0c9e9aaf 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end' | 'player__on_enter' | 'player__intent__media_status_finished' | 'player__intent__media_status_paused' | 'player__intent__media_status_stopped' | 'player__intent__media_status_failed' | 'search__on_enter' | 'search__intent__search_query' | 'search__intent__search'; +export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end' | 'player__on_enter' | 'player__intent__media_status_finished' | 'player__intent__media_status_paused' | 'player__intent__media_status_stopped' | 'player__intent__media_status_failed' | 'search__on_enter' | 'search__intent__search_query' | 'search__intent__search' | 'collections__on_enter' | 'collections__intent__bookshelf' | 'collections__intent__by_genre' | 'collections__intent__by_theme' | 'collections__intent__help' | 'collections__intent__fallback' | 'collections__intent__fallback_end' | 'collections__intent__silence' | 'collections__intent__silence_end'; From 9ee2e47ef65eb9f352b95305a34032e5587dd182 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 17 Feb 2022 19:27:17 +0100 Subject: [PATCH 147/180] fix: test selection --- webhooks/functions/src/controller/Machine.ts | 4 +- .../src/controller/handler/selection.ts | 37 ++++++++++++++----- webhooks/functions/src/sdk/selection.test.ts | 30 +++++++-------- 3 files changed, 44 insertions(+), 27 deletions(-) diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index fda0f213..5a0e1762 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -286,7 +286,7 @@ export class Machine { public async getNexLinkPublicationWithUrl(url: string) { const feed = await this.feedRequest(url); - const nextUrl = feed.links?.next[0].url; + const nextUrl = (feed.links?.next || [])[0]?.url; if (this.isValidHttpUrl(nextUrl) && await this.isPublicationAvailable(nextUrl)) { return nextUrl; @@ -296,7 +296,7 @@ export class Machine { public async getNexLinkGroupWithUrl(url: string) { const feed = await this.feedRequest(url); - const nextUrl = feed.links?.next[0].url; + const nextUrl = (feed.links?.next || [])[0]?.url; if (this.isValidHttpUrl(nextUrl) && await this.isGroupAvailable(nextUrl)) { return nextUrl; } diff --git a/webhooks/functions/src/controller/handler/selection.ts b/webhooks/functions/src/controller/handler/selection.ts index 370e03cd..50187c75 100644 --- a/webhooks/functions/src/controller/handler/selection.ts +++ b/webhooks/functions/src/controller/handler/selection.ts @@ -24,7 +24,8 @@ const enter: THandlerFn = async (m) => { if (state === "RUNNING") { - const isEmpty = kind === "GROUP" ? await m.isGroupAvailable(url) : await m.isPublicationAvailable(url); + const isAvailable = kind === "GROUP" ? await m.isGroupAvailable(url) : await m.isPublicationAvailable(url); + const isEmpty = !isAvailable; if (isEmpty) { m.say('selection.enter.empty.1'); m.nextScene = "home_user"; @@ -36,16 +37,31 @@ const enter: THandlerFn = async (m) => { // redirect to nextScene 'selection' for group // or 'player-prequel' for a publication - const handler = m.selectionSession.from; - // intro - if (handler === "home_user__intent__bookshelf") { - const {publication} = await m.getPublicationFromFeed(url); // @TODO fix it .. twice call to api - m.say('selection.enter.bookshelf.first', {number: publication.length}); - } else if (handler === "home_user__intent__search") { - const {length} = await m.getPublicationFromFeed(url); // @TODO fix it .. twice call to api - m.say('selection.enter.search', {number: length}); + if (m.selectionSession.nextUrlCounter) { + const nextLink = kind === "GROUP" ? await m.getNexLinkGroupWithUrl(url) : await m.getNexLinkPublicationWithUrl(url); + if (nextLink) { + + } else { + if (kind === "GROUP") { + m.say("selection.enter.lastPage.group"); + } else { + m.say("selection.enter.lastPage.publication"); + } + } + + } else { + const handler = m.selectionSession.from; + // intro + if (handler === "home_user__intent__bookshelf") { + const {publication} = await m.getPublicationFromFeed(url); // @TODO fix it .. twice call to api + m.say('selection.enter.bookshelf.first', {number: publication.length}); + } else if (handler === "home_user__intent__search") { + const {length} = await m.getPublicationFromFeed(url); // @TODO fix it .. twice call to api + m.say('selection.enter.search', {number: length}); + } } - // @TODO handle collection group or publication + + // @TODO handle collection group or publication // list groups or publication m.say('selection.enter.common.1'); @@ -57,6 +73,7 @@ const enter: THandlerFn = async (m) => { // outro + const handler = m.selectionSession.from; if (handler === "home_user__intent__bookshelf") { m.say('selection.enter.bookshelf.second'); } diff --git a/webhooks/functions/src/sdk/selection.test.ts b/webhooks/functions/src/sdk/selection.test.ts index 5602d44d..568c9958 100644 --- a/webhooks/functions/src/sdk/selection.test.ts +++ b/webhooks/functions/src/sdk/selection.test.ts @@ -56,7 +56,7 @@ describe(scene + ' handler', () => { const messageHelpers = (number: number, it: Array<[nb: number, title: string]>) => { const a = 'Pick one of these by saying their numbers.\n'; const b = it.reduce((pv, [nb, title]) => pv + `${nb}. ${title}\n`, ''); - const c = 'Which one would you like to start reading? Or perhaps you\'d like to explore the other titles on your bookshelf?\n'; + const c = 'Which one would you like to start reading?\n'; return a + b + c; }; @@ -107,7 +107,7 @@ describe(scene + ' handler', () => { // 13) machine finish // 15) table de routage prochaine scene en fonction de sceneFrom - const message = `Oops, something went wrong. I will send you back to the home menu\n`; + const message = `Oops, something went wrong. I will exit the app. Feel free to reopen it as soon as possible.`; const pullData = parsedDataClone(); @@ -118,7 +118,7 @@ describe(scene + ' handler', () => { data.prompt.firstSimple.speech.should.to.be.eq(message); // must redirect to home_user when the state machine not initialized - data.scene.next.name.should.to.be.eq('home_user'); + data.scene.next.name.should.to.be.eq('actions.scene.END_CONVERSATION'); }); it('on enter - state running - no url', async () => { @@ -129,9 +129,9 @@ describe(scene + ' handler', () => { pullData.session.scene.selection.state = 'RUNNING'; const data = await expressMocked(body, headers, pullData); - const message = `Oops, something went wrong. I will send you back to the home menu\n`; + const message = `Oops, something went wrong. I will exit the app. Feel free to reopen it as soon as possible.`; data.prompt.firstSimple.speech.should.to.be.eq(message); - data.scene.next.name.should.to.be.eq('home_user'); + data.scene.next.name.should.to.be.eq('actions.scene.END_CONVERSATION'); }); const newFeed = (): Partial => ({ @@ -251,19 +251,19 @@ describe(scene + ' handler', () => { { selfLink: { title: 'first group', - url: '', + url: 'http://my.url', }, }, { selfLink: { title: 'second group', - url: '', + url: 'http://my.url', }, }, { selfLink: { title: 'third group', - url: '', + url: 'http://my.url', }, }, ], @@ -290,7 +290,7 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers, pullData, feed); data.prompt.firstSimple.speech.should.to.be.eq(message); - data.scene.next.name.should.to.be.eq('selection'); + // data.scene.next.name.should.to.be.eq('selection'); }); it('on enter - state running - group list first page with no next link', async () => { @@ -304,7 +304,7 @@ describe(scene + ' handler', () => { // must say the first page data.prompt.firstSimple.speech.should.to.be.eq(message); - data.scene.next.name.should.to.be.eq('selection'); + // data.scene.next.name.should.to.be.eq('selection'); }); it('on enter - state running - publication list last page', async () => { @@ -318,7 +318,7 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers, pullData, feed); data.prompt.firstSimple.speech.should.to.be.eq('Here\'s the last available books\n' + message); - data.scene.next.name.should.to.be.eq('selection'); + // data.scene.next.name.should.to.be.eq('selection'); }); it('on enter - state running - group list last page', async () => { @@ -333,7 +333,7 @@ describe(scene + ' handler', () => { // must say the first page data.prompt.firstSimple.speech.should.to.be.eq('Here\'s the last available groups\n' + message); - data.scene.next.name.should.to.be.eq('selection'); + // data.scene.next.name.should.to.be.eq('selection'); }); it('on enter - state running - publication list page > 0', async () => { @@ -353,7 +353,7 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers, pullData, feed); data.prompt.firstSimple.speech.should.to.be.eq(message); - data.scene.next.name.should.to.be.eq('selection'); + // data.scene.next.name.should.to.be.eq('selection'); }); it('on enter - state running - group list last page > 0', async () => { @@ -374,7 +374,7 @@ describe(scene + ' handler', () => { // must say the first page data.prompt.firstSimple.speech.should.to.be.eq(message); - data.scene.next.name.should.to.be.eq('selection'); + // data.scene.next.name.should.to.be.eq('selection'); }); it('on enter - state running - publication list with next page - from bookshelf', async () => { @@ -397,7 +397,7 @@ describe(scene + ' handler', () => { const message2 = 'Here are the first 3 titles on your bookshelf:\n' + message + 'Or perhaps you\'d like to explore the other titles on your bookshelf?\n'; data.prompt.firstSimple.speech.should.to.be.eq(message2); - data.scene.next.name.should.to.be.eq('selection'); + // data.scene.next.name.should.to.be.eq('selection'); }); // @TODO From f39f98a39370672c1553fda099d578a8cb184a7b Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Thu, 17 Feb 2022 20:06:55 +0100 Subject: [PATCH 148/180] feat: player_prequel scene --- sdk/custom/scenes/player_prequel.yaml | 9 ++ sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 3 + webhooks/functions/src/controller/Machine.ts | 14 ++ .../functions/src/controller/handler/index.ts | 2 + .../src/controller/handler/player_prequel.ts | 49 ++++++ .../functions/src/sdk/player_prequel.test.ts | 153 ++++++++++++++++++ webhooks/functions/src/translation/en/en.json | 3 +- webhooks/functions/src/typings/i18n.d.ts | 4 +- .../functions/src/typings/sdkHandler.d.ts | 2 +- webhooks/functions/src/typings/sdkScene.d.ts | 2 +- 10 files changed, 236 insertions(+), 5 deletions(-) create mode 100644 sdk/custom/scenes/player_prequel.yaml create mode 100644 webhooks/functions/src/controller/handler/player_prequel.ts create mode 100644 webhooks/functions/src/sdk/player_prequel.test.ts diff --git a/sdk/custom/scenes/player_prequel.yaml b/sdk/custom/scenes/player_prequel.yaml new file mode 100644 index 00000000..e3439cfa --- /dev/null +++ b/sdk/custom/scenes/player_prequel.yaml @@ -0,0 +1,9 @@ +intentEvents: +- handler: + webhookHandler: player_prequel__intent__yes + intent: "yes" +- handler: + webhookHandler: player_prequel__intent__no + intent: "no" +onEnter: + webhookHandler: player_prequel__on_enter diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index b3220156..7fce1ff0 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -80,6 +80,9 @@ handlers: - name: collections__intent__fallback_end - name: collections__intent__silence - name: collections__intent__silence_end +- name: player_prequel__on_enter +- name: player_prequel__intent__yes +- name: player_prequel__intent__no httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 5a0e1762..f47c3680 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -177,6 +177,20 @@ export class Machine { this._model.store.session.scene.search = d; } + public isCurrentlyPlaying() { + const {url, time, index} = this.playerCurrent; + if (!this.isValidHttpUrl(url)) { + throw new Error('not valid playing url'); + } + if (!time || !index) { + return false; + } + if (time > 0 || index > 0) { + return true; + } + return false; + } + public get playerCurrent() { ok(this._model); return this._model.store.player.current; diff --git a/webhooks/functions/src/controller/handler/index.ts b/webhooks/functions/src/controller/handler/index.ts index 64a37c08..682a7c5c 100644 --- a/webhooks/functions/src/controller/handler/index.ts +++ b/webhooks/functions/src/controller/handler/index.ts @@ -7,6 +7,7 @@ import { home_user } from "./home_user"; import { info } from "./info"; import { main } from "./main"; import { player } from "./player"; +import { player_prequel } from "./player_prequel"; import { search } from "./search"; import { selection } from "./selection"; @@ -51,4 +52,5 @@ export const handler = (app = new Assistant({})) => { player(app); search(app); collections(app); + player_prequel(app); } diff --git a/webhooks/functions/src/controller/handler/player_prequel.ts b/webhooks/functions/src/controller/handler/player_prequel.ts new file mode 100644 index 00000000..6b35850f --- /dev/null +++ b/webhooks/functions/src/controller/handler/player_prequel.ts @@ -0,0 +1,49 @@ +import { THandlerFn } from "../../type"; +import { Assistant } from "../Assistant"; + +export const player_prequel = (app: Assistant) => { + + app.handle("player_prequel__on_enter", enter); + app.handle("player_prequel__intent__yes", yes); + app.handle("player_prequel__intent__no", no); + +} + +const enter: THandlerFn = async (m) => { + + const isPlaying = m.isCurrentlyPlaying(); + + if (isPlaying) { + m.say("player.askResumeLastOffset"); + } else { + m.nextScene = "player"; + } + m.playerCurrent.playing = true; + +} + +const intro: THandlerFn = async (m) => { + + const {title} = await m.getCurrentPlayingTitleAndChapter(); + m.say("player.start", {title}); +} + +const yes: THandlerFn = async (m) => { + + await intro(m); + m.playerCurrent.playing = true; + m.nextScene = "player"; +} + +const no: THandlerFn = async (m) => { + + m.playerCurrent.index = 0; + m.playerCurrent.time = 0; + + await intro(m); + m.playerCurrent.playing = true; + m.nextScene = "player"; +} + + + diff --git a/webhooks/functions/src/sdk/player_prequel.test.ts b/webhooks/functions/src/sdk/player_prequel.test.ts new file mode 100644 index 00000000..3f2a0d2e --- /dev/null +++ b/webhooks/functions/src/sdk/player_prequel.test.ts @@ -0,0 +1,153 @@ +import {expressMocked, shell, storageModelMocked} from '../test/utils.test'; +import * as chai from 'chai'; +// import * as sinon from 'sinon'; +import {headers, body} from './conv.test'; +import {parsedDataClone} from '../model/data.model.test'; +import {IWebPubView} from 'opds-fetcher-parser/build/src/interface/webpub'; + + +chai.should(); + +const scene = 'player_prequel'; + +const yaml = `intentEvents: +- handler: + webhookHandler: player_prequel__intent__yes + intent: "yes" +- handler: + webhookHandler: player_prequel__intent__no + intent: "no" +onEnter: + webhookHandler: player_prequel__on_enter +`; + +describe(scene + ' handler', () => { + describe('sdk', () => { + it('check main scene', (done) => { + shell(`cat custom/scenes/${scene}.yaml`, (stdout) => { + stdout.should.to.be.eq(yaml); + }, done); + }); + }); + + describe('app', () => { + it('on enter - no need to ask to resume bad url', async () => { + body.handler.name = 'player_prequel__on_enter'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + + const message = `Oops, something went wrong. I will exit the app. Feel free to reopen it as soon as possible.`; + + const model = await storageModelMocked(pullData); + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + data.scene.next.name.should.to.be.eq('actions.scene.END_CONVERSATION'); + }); + it('on enter - no need to ask to resume - start from scratch', async () => { + body.handler.name = 'player_prequel__on_enter'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + pullData.player.current.index = 0; + pullData.player.current.playing = false; + pullData.player.current.time = 0; + pullData.player.current.url = 'http://my.url'; + + const webpub: Partial = { + title: 'my title', + authors: [ + 'hello', + 'world', + ], + }; + + const model = await storageModelMocked(pullData); + const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); + + data.scene.next.name.should.to.be.eq('player'); + }); + it('on enter - need to ask - and answer yes or no', async () => { + body.handler.name = 'player_prequel__on_enter'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + pullData.player.current.index = 2; + pullData.player.current.playing = false; + pullData.player.current.time = 330; + pullData.player.current.url = 'http://my.url'; + + const webpub: Partial = { + title: 'my title', + authors: [ + 'hello', + 'world', + ], + }; + + const message = 'Do you want to pick up where it left off ?\n'; + + const model = await storageModelMocked(pullData); + const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + }); + + it('no', async () => { + body.handler.name = 'player_prequel__intent__no'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + pullData.player.current.index = 2; + pullData.player.current.playing = false; + pullData.player.current.time = 330; + pullData.player.current.url = 'http://my.url'; + + const webpub: Partial = { + title: 'my title', + authors: [ + 'hello', + 'world', + ], + }; + + const model = await storageModelMocked(pullData); + const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); + + model.data.store.player.current.index?.should.to.be.eq(0); + model.data.store.player.current.playing.should.to.be.eq(true); + model.data.store.player.current.url?.should.to.be.eq('http://my.url'); + model.data.store.player.current.time?.should.to.be.eq(0); + data.scene.next.name.should.to.be.eq('player'); + }); + + it('yes', async () => { + body.handler.name = 'player_prequel__intent__yes'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + pullData.player.current.index = 2; + pullData.player.current.playing = false; + pullData.player.current.time = 330; + pullData.player.current.url = 'http://my.url'; + + const webpub: Partial = { + title: 'my title', + authors: [ + 'hello', + 'world', + ], + }; + + const model = await storageModelMocked(pullData); + const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); + + model.data.store.player.current.index?.should.to.be.eq(2); + model.data.store.player.current.playing.should.to.be.eq(true); + model.data.store.player.current.url?.should.to.be.eq('http://my.url'); + model.data.store.player.current.time?.should.to.be.eq(330); + data.scene.next.name.should.to.be.eq('player'); + }); + }); +}); diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index 78cb5153..3c75ec65 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -106,7 +106,8 @@ } }, "player": { - "start": "I start reading {{- title}}" + "start": "I start reading {{- title}}", + "askResumeLastOffset": "Do you want to pick up where it left off ?" }, "collections": { "enter": { diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index 5c287b20..aaaf08bb 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "player.start" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", + "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "player.start" | "player.askResumeLastOffset" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:player.start" | "en:collections.enter.1" | "en:collections.help.1" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", + "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:player.start" | "en:player.askResumeLastOffset" | "en:collections.enter.1" | "en:collections.help.1" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index 0c9e9aaf..f2216e8d 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end' | 'player__on_enter' | 'player__intent__media_status_finished' | 'player__intent__media_status_paused' | 'player__intent__media_status_stopped' | 'player__intent__media_status_failed' | 'search__on_enter' | 'search__intent__search_query' | 'search__intent__search' | 'collections__on_enter' | 'collections__intent__bookshelf' | 'collections__intent__by_genre' | 'collections__intent__by_theme' | 'collections__intent__help' | 'collections__intent__fallback' | 'collections__intent__fallback_end' | 'collections__intent__silence' | 'collections__intent__silence_end'; +export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end' | 'player__on_enter' | 'player__intent__media_status_finished' | 'player__intent__media_status_paused' | 'player__intent__media_status_stopped' | 'player__intent__media_status_failed' | 'search__on_enter' | 'search__intent__search_query' | 'search__intent__search' | 'collections__on_enter' | 'collections__intent__bookshelf' | 'collections__intent__by_genre' | 'collections__intent__by_theme' | 'collections__intent__help' | 'collections__intent__fallback' | 'collections__intent__fallback_end' | 'collections__intent__silence' | 'collections__intent__silence_end' | 'player_prequel__on_enter' | 'player_prequel__intent__yes' | 'player_prequel__intent__no'; diff --git a/webhooks/functions/src/typings/sdkScene.d.ts b/webhooks/functions/src/typings/sdkScene.d.ts index 0b4e5ad9..472d63f2 100644 --- a/webhooks/functions/src/typings/sdkScene.d.ts +++ b/webhooks/functions/src/typings/sdkScene.d.ts @@ -1,4 +1,4 @@ // npm run scene-typed ; -export type TSdkScene = 'collections' | 'home_new_user' | 'home_new_user_AccountLinking' | 'home_new_user_maybe_later' | 'home_new_user_no' | 'home_user' | 'info' | 'player' | 'search' | 'selection'; +export type TSdkScene = 'collections' | 'home_new_user' | 'home_new_user_AccountLinking' | 'home_new_user_maybe_later' | 'home_new_user_no' | 'home_user' | 'info' | 'player' | 'player_prequel' | 'search' | 'selection'; From 6d9fa55b571dd055c9c04ebdea3a03ae1077cc64 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 22 Feb 2022 17:44:59 +0100 Subject: [PATCH 149/180] fix: home_user session state --- webhooks/functions/src/controller/Machine.ts | 6 +++++ .../src/controller/handler/home_user.ts | 2 +- webhooks/functions/src/sdk/home_user.test.ts | 27 ++++++++++--------- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index f47c3680..f1d66dba 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -498,6 +498,11 @@ export class Machine { return feed; } + private setSessionStateHomeUser() { + ok(this._model); + this._model.store.session.scene['home_user'].state = 'SESSION'; + } + private removeSessionDataWhenNewUserSession() { if (!this._model) { return; @@ -513,6 +518,7 @@ export class Machine { const sameSession = id === idFromStore; if (sameSession) { console.info('MIDDLEWARE :: Session in progress'); + this.setSessionStateHomeUser(); } else { console.info('MIDDLEWARE :: new SESSION'); this._model.store.session = { diff --git a/webhooks/functions/src/controller/handler/home_user.ts b/webhooks/functions/src/controller/handler/home_user.ts index 2b8b639d..fdbd378d 100644 --- a/webhooks/functions/src/controller/handler/home_user.ts +++ b/webhooks/functions/src/controller/handler/home_user.ts @@ -20,7 +20,7 @@ export const home_user = (app: Assistant) => { const enter: THandlerFn = async (m) => { - const state = m.getSessionState("home_user") + const state = m.getSessionState("home_user"); if (state === "SESSION") { // aka there is a session : the user discovered the app m.say("home_user.enter.regular.1"); diff --git a/webhooks/functions/src/sdk/home_user.test.ts b/webhooks/functions/src/sdk/home_user.test.ts index 1b8ffc73..c55c867b 100644 --- a/webhooks/functions/src/sdk/home_user.test.ts +++ b/webhooks/functions/src/sdk/home_user.test.ts @@ -62,6 +62,7 @@ describe('home_user handler', () => { it('on enter', async () => { body.handler.name = 'home_user__on_enter'; body.scene.name = scene; + body.session.id = 'on enter'; // new session const message = `Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?\n`; const data = await expressMocked(body, headers); @@ -71,45 +72,46 @@ describe('home_user handler', () => { it('on enter with session state but new session', async () => { body.handler.name = 'home_user__on_enter'; body.scene.name = scene; - body.session.id = 'newSession'; // new session + body.session.id = 'id'; // new session const message = `Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?\n`; const pullData = parsedDataClone(); - pullData.session.scene.home_user.state = 'SESSION'; - pullData.user.sessionId = 'id'; + const model = await storageModelMocked(pullData); - const data = await expressMocked(body, headers, pullData); + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + model.data.store.session.scene.home_user.state.should.not.to.be.eq('SESSION'); data.prompt.firstSimple.speech.should.to.be.eq(message); }); it('on enter with session state but new session undefined so the session data is not removed', async () => { body.handler.name = 'home_user__on_enter'; body.scene.name = scene; - body.session.id = 'newSession'; // new session + body.session.id = 'on enter with session state but new session undefined so the session data is not removed'; // new session const message = `Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?\n`; const pullData = parsedDataClone(); - pullData.session.scene.home_user.state = 'SESSION'; - pullData.user.sessionId = 'id'; + const model = await storageModelMocked(pullData); - const data = await expressMocked(body, headers, pullData); + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + model.data.store.session.scene.home_user.state.should.not.to.be.eq('SESSION'); data.prompt.firstSimple.speech.should.to.be.eq(message); }); it('on enter with session state', async () => { body.handler.name = 'home_user__on_enter'; body.scene.name = scene; - body.session.id = 'id'; + body.session.id = 'test'; const message = `What would you like to do?\n`; const pullData = parsedDataClone(); - pullData.session.scene.home_user.state = 'SESSION'; - pullData.user.sessionId = 'id'; + const model = await storageModelMocked(pullData); - const data = await expressMocked(body, headers, pullData); + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + model.data.store.session.scene.home_user.state.should.to.be.eq('SESSION'); data.prompt.firstSimple.speech.should.to.be.eq(message); }); it('on enter with a current playing no history', async () => { body.handler.name = 'home_user__on_enter'; body.scene.name = scene; + body.session.id = 'on enter with a current playing no history'; const message = `Last time, you read Chapter 10 of my title, hello, which you can resume where you left off.\nYou can search for a new one alltogether.\nWhat would you like to do?\n`; const pullData = parsedDataClone(); @@ -135,6 +137,7 @@ describe('home_user handler', () => { it('on enter with a current playing and history', async () => { body.handler.name = 'home_user__on_enter'; body.scene.name = scene; + body.session.id = 'on enter with a current playing and history'; const message = `Last time, you read Chapter 10 of my title, hello, which you can resume where you left off.\nYou are also reading 4 other recent books, which you can choose from.\nYou can search for a new one alltogether.\nWhat would you like to do?\n`; const pullData = parsedDataClone(); From 87d0a3c18d57f616f03918796ce89a341eef649b Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 22 Feb 2022 18:09:03 +0100 Subject: [PATCH 150/180] fix: home_user repeat state --- webhooks/functions/src/controller/Machine.ts | 12 ++++++------ .../functions/src/controller/handler/home_user.ts | 3 ++- webhooks/functions/src/model/storage.interface.ts | 2 +- webhooks/functions/src/sdk/home_user.test.ts | 6 +++++- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index f1d66dba..b114b27b 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -129,6 +129,11 @@ export class Machine { return false; } + public setSessionState(scene: T, state: ISessionScene[T]['state']) { + ok(this._model); + this._model.store.session.scene[scene].state = state; + } + public get playingInProgress() { ok(this._model); return this._model.store.player.current.playing; @@ -498,11 +503,6 @@ export class Machine { return feed; } - private setSessionStateHomeUser() { - ok(this._model); - this._model.store.session.scene['home_user'].state = 'SESSION'; - } - private removeSessionDataWhenNewUserSession() { if (!this._model) { return; @@ -518,7 +518,7 @@ export class Machine { const sameSession = id === idFromStore; if (sameSession) { console.info('MIDDLEWARE :: Session in progress'); - this.setSessionStateHomeUser(); + this.setSessionState('home_user', 'SESSION'); } else { console.info('MIDDLEWARE :: new SESSION'); this._model.store.session = { diff --git a/webhooks/functions/src/controller/handler/home_user.ts b/webhooks/functions/src/controller/handler/home_user.ts index fdbd378d..f00c20fb 100644 --- a/webhooks/functions/src/controller/handler/home_user.ts +++ b/webhooks/functions/src/controller/handler/home_user.ts @@ -89,6 +89,7 @@ const help: THandlerFn = (m) => { } const repeat: THandlerFn = (m) => { - + + m.setSessionState("home_user", "REPEAT"); m.nextScene = "home_user"; } \ No newline at end of file diff --git a/webhooks/functions/src/model/storage.interface.ts b/webhooks/functions/src/model/storage.interface.ts index e2a0d2cd..f9715671 100644 --- a/webhooks/functions/src/model/storage.interface.ts +++ b/webhooks/functions/src/model/storage.interface.ts @@ -20,7 +20,7 @@ export interface IStoragePlayer { export type TStateDefault = 'DEFAULT' export type TStateAuthentication = 'NO_LINKED' | 'NEWLY_LINKED' | 'LINKED' | TStateDefault; -export type TStateHomeUser = 'SESSION' | TStateDefault; +export type TStateHomeUser = 'SESSION' | 'REPEAT' | TStateDefault; export type TStateSelection = 'RUNNING' | 'FINISH' | TStateDefault; export type TKindSelection = 'PUBLICATION' | 'GROUP'; export type TStateSearch = 'RUNNING' | 'FINISH' | TStateDefault; diff --git a/webhooks/functions/src/sdk/home_user.test.ts b/webhooks/functions/src/sdk/home_user.test.ts index c55c867b..2cbe6115 100644 --- a/webhooks/functions/src/sdk/home_user.test.ts +++ b/webhooks/functions/src/sdk/home_user.test.ts @@ -176,7 +176,11 @@ describe('home_user handler', () => { body.handler.name = 'home_user__intent__repeat'; body.scene.name = scene; - const data = await expressMocked(body, headers); + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + model.data.store.session.scene.home_user.state.should.to.be.eq('REPEAT'); data.scene.next.name.should.to.be.eq('home_user'); }); From 3d990341aa34748608fcd78d00957159683bbc01 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 22 Feb 2022 19:04:37 +0100 Subject: [PATCH 151/180] fix: home_user search intent --- webhooks/functions/src/controller/Machine.ts | 21 +++++++++++++--- .../src/controller/handler/home_user.ts | 3 +++ .../src/controller/handler/search.ts | 17 +++---------- webhooks/functions/src/sdk/home_user.test.ts | 25 +++++++++++++++++++ 4 files changed, 50 insertions(+), 16 deletions(-) diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index b114b27b..29f12fc8 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -296,13 +296,28 @@ export class Machine { } public get querySearch() { - const v = this._conv.intent.params?.query.resolved; + const v = this._conv.intent.params?.query?.resolved; if (v && typeof v === 'string') { return v; } return undefined; } + public setQuerySearch() { + const query = this.querySearch; + if (!query) { + this.searchSession = { + query: '', + state: 'RUNNING', + }; + } else { + this.searchSession = { + query, + state: 'FINISH', + }; + } + } + public async getNexLinkPublicationWithUrl(url: string) { const feed = await this.feedRequest(url); const nextUrl = (feed.links?.next || [])[0]?.url; @@ -337,8 +352,8 @@ export class Machine { .filter(({openAccessLinks: l}) /* : l is IOpdsLinkView[]*/ => { return ( Array.isArray(l) && - l[0] && - this.isValidHttpUrl(l[0].url) + l[0] && + this.isValidHttpUrl(l[0].url) ); }) .slice(0, PADDING_PUB) diff --git a/webhooks/functions/src/controller/handler/home_user.ts b/webhooks/functions/src/controller/handler/home_user.ts index f00c20fb..bb978b69 100644 --- a/webhooks/functions/src/controller/handler/home_user.ts +++ b/webhooks/functions/src/controller/handler/home_user.ts @@ -64,6 +64,9 @@ const enter: THandlerFn = async (m) => { } const search: THandlerFn = (m) => { + + // query from search intent + m.setQuerySearch(); m.nextScene = "search"; } diff --git a/webhooks/functions/src/controller/handler/search.ts b/webhooks/functions/src/controller/handler/search.ts index eae2f0c4..815aa137 100644 --- a/webhooks/functions/src/controller/handler/search.ts +++ b/webhooks/functions/src/controller/handler/search.ts @@ -37,18 +37,9 @@ const enter: THandlerFn = (m) => { const query: THandlerFn = (m) => { - const query = m.querySearch; - if (!query) { - m.searchSession = { - query: '', - state: "RUNNING", - } - } else { - m.searchSession = { - query, - state: "FINISH", - } - } - + // query from search intent + // query from search intent and search_query intent + // same intent but search_query as a free text parsing + m.setQuerySearch(); m.nextScene = "search"; } diff --git a/webhooks/functions/src/sdk/home_user.test.ts b/webhooks/functions/src/sdk/home_user.test.ts index 2cbe6115..709cb47d 100644 --- a/webhooks/functions/src/sdk/home_user.test.ts +++ b/webhooks/functions/src/sdk/home_user.test.ts @@ -192,6 +192,31 @@ describe('home_user handler', () => { data.scene.next.name.should.to.be.eq('search'); }); + it('search with query', async () => { + body.handler.name = 'home_user__intent__search'; + body.scene.name = scene; + body.intent.params = { + query: { + original: 'my query', + resolved: 'my query', + }, + }; + + // parse query and state = FINISH + + const pullData = parsedDataClone(); + + pullData.session.scene.search.query = ''; + pullData.session.scene.search.state = 'DEFAULT'; + + const model = await storageModelMocked(pullData); + + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + + model.data.store.session.scene.search.state.should.to.be.eq('FINISH'); + model.data.store.session.scene.search.query.should.to.be.eq('my query'); + data.scene.next.name.should.to.be.eq('search'); + }); it('browse collections', async () => { body.handler.name = 'home_user__intent__collections'; From 59cdb1a6392183f46b408055d2ec070a8ca0098c Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 23 Feb 2022 11:36:39 +0100 Subject: [PATCH 152/180] fix: info name --- webhooks/functions/src/sdk/info.test.ts | 2 +- webhooks/functions/src/translation/en/en.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/webhooks/functions/src/sdk/info.test.ts b/webhooks/functions/src/sdk/info.test.ts index 4215b092..85420f37 100644 --- a/webhooks/functions/src/sdk/info.test.ts +++ b/webhooks/functions/src/sdk/info.test.ts @@ -86,7 +86,7 @@ describe(scene + ' handler', () => { data.scene.next.name.should.to.be.eq('info'); }); - const help = `If you'd like to learn more about CELA membership - you can ask me by saying 'membership', or simply say 'stop' to exit this skill. If you have any other questions, we recommend reaching out to your local library for support. I'm listening?\n`; + const help = `If you'd like to learn more about EDRLAB membership - you can ask me by saying 'membership', or simply say 'stop' to exit this skill. If you have any other questions, we recommend reaching out to your local library for support. I'm listening?\n`; it('help', async () => { body.handler.name = 'info__intent__help'; diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index 3c75ec65..356a3cb8 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -44,7 +44,7 @@ "1": "{{- name}} about text. Would you like to find out more about {{- name}} membership, or would you prefer to exit this skill?" }, "help": { - "1": "If you'd like to learn more about CELA membership - you can ask me by saying 'membership', or simply say 'stop' to exit this skill. If you have any other questions, we recommend reaching out to your local library for support. I'm listening?" + "1": "If you'd like to learn more about {{- name}} membership - you can ask me by saying 'membership', or simply say 'stop' to exit this skill. If you have any other questions, we recommend reaching out to your local library for support. I'm listening?" }, "yesOrMembership": { "1": "Signing up is easy, you can head on over to the CELA online platform at 'URL'. Keep the name of your local library and your library or SQLA number handy, that's all you'll need. You can also ask for help at your local library. As soon as your membership is activated, you can come back to start using the {{- name}} library via Alexa, by saying 'Hey Google, launch {{- name}}'" From a301ddc6909fabb4b40ecf3b74d6931ed0177067 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 23 Feb 2022 11:52:55 +0100 Subject: [PATCH 153/180] fix: empty search result search scene to selection => is empty => returns to search scene with a specific message with 'from' --- webhooks/functions/src/controller/Machine.ts | 5 +- .../src/controller/handler/search.ts | 12 +++- .../src/controller/handler/selection.ts | 15 +++-- .../functions/src/model/data.model.test.ts | 2 + webhooks/functions/src/model/storage.dto.ts | 1 + .../functions/src/model/storage.interface.ts | 1 + webhooks/functions/src/sdk/search.test.ts | 18 ++++++ webhooks/functions/src/sdk/selection.test.ts | 57 +++++++++++++++++++ webhooks/functions/src/translation/en/en.json | 7 ++- webhooks/functions/src/typings/i18n.d.ts | 4 +- 10 files changed, 111 insertions(+), 11 deletions(-) diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 29f12fc8..5465591f 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -303,17 +303,19 @@ export class Machine { return undefined; } - public setQuerySearch() { + public setQuerySearch(scene: TSdkHandler = 'main') { const query = this.querySearch; if (!query) { this.searchSession = { query: '', state: 'RUNNING', + from: scene, }; } else { this.searchSession = { query, state: 'FINISH', + from: scene, }; } } @@ -545,6 +547,7 @@ export class Machine { 'search': { state: 'DEFAULT', query: '', + from: 'main', }, }, }; diff --git a/webhooks/functions/src/controller/handler/search.ts b/webhooks/functions/src/controller/handler/search.ts index 815aa137..8650bdc2 100644 --- a/webhooks/functions/src/controller/handler/search.ts +++ b/webhooks/functions/src/controller/handler/search.ts @@ -11,22 +11,28 @@ export const search = (app: Assistant) => { const enter: THandlerFn = (m) => { - const { state, query } = m.searchSession; + const { state, query, from } = m.searchSession; if (state === "RUNNING") { - m.say('search.enter.1'); + if (from === "selection__on_enter") { + m.say("search.enter.2"); + m.searchSession.from = 'main'; // reset + } else { + m.say('search.enter.1'); + } // wait intent search query } else if (state === "FINISH") { if (!query) { + m.searchSession.state = "RUNNING"; m.nextScene = "search"; return ; } m.initAndGoToSelectionSession({ kind: 'PUBLICATION', - url: SEARCH_URL_FN(encodeURIComponent(query)), // @todo do you have to encode Url ? + url: SEARCH_URL_FN(encodeURIComponent(query)), from: 'search__on_enter', }); diff --git a/webhooks/functions/src/controller/handler/selection.ts b/webhooks/functions/src/controller/handler/selection.ts index 50187c75..4528f553 100644 --- a/webhooks/functions/src/controller/handler/selection.ts +++ b/webhooks/functions/src/controller/handler/selection.ts @@ -21,14 +21,23 @@ const enter: THandlerFn = async (m) => { const { state, url, nbChoice } = m.selectionSession; const kind = m.selectionSession.kind; + const handler = m.selectionSession.from; if (state === "RUNNING") { const isAvailable = kind === "GROUP" ? await m.isGroupAvailable(url) : await m.isPublicationAvailable(url); const isEmpty = !isAvailable; if (isEmpty) { - m.say('selection.enter.empty.1'); - m.nextScene = "home_user"; + if (handler === "search__on_enter") { + m.say("search.empty.1", {name: NAME}); + m.nextScene = "search"; + m.searchSession.query = ''; + m.searchSession.state = 'RUNNING'; + m.searchSession.from = "selection__on_enter"; + } else { + m.say('selection.enter.empty.1'); + m.nextScene = "home_user"; + } return ; } @@ -50,7 +59,6 @@ const enter: THandlerFn = async (m) => { } } else { - const handler = m.selectionSession.from; // intro if (handler === "home_user__intent__bookshelf") { const {publication} = await m.getPublicationFromFeed(url); // @TODO fix it .. twice call to api @@ -73,7 +81,6 @@ const enter: THandlerFn = async (m) => { // outro - const handler = m.selectionSession.from; if (handler === "home_user__intent__bookshelf") { m.say('selection.enter.bookshelf.second'); } diff --git a/webhooks/functions/src/model/data.model.test.ts b/webhooks/functions/src/model/data.model.test.ts index 96c77e2d..453fa567 100644 --- a/webhooks/functions/src/model/data.model.test.ts +++ b/webhooks/functions/src/model/data.model.test.ts @@ -27,6 +27,7 @@ export const freshDataClone = () => Object.assign({ search: { state: 'DEFAULT', query: '', + from: 'main', }, }, }, @@ -60,6 +61,7 @@ export const parsedDataClone = (): IStorage => Object.assign({ search: { state: 'DEFAULT', query: '', + from: 'main', }, }, }, diff --git a/webhooks/functions/src/model/storage.dto.ts b/webhooks/functions/src/model/storage.dto.ts index 288bd4de..5a91da0a 100644 --- a/webhooks/functions/src/model/storage.dto.ts +++ b/webhooks/functions/src/model/storage.dto.ts @@ -98,6 +98,7 @@ class StorageSessionDto implements IStorageSession { 'search': { state: 'DEFAULT', query: '', + from: 'main', }, }; } diff --git a/webhooks/functions/src/model/storage.interface.ts b/webhooks/functions/src/model/storage.interface.ts index f9715671..ef0e2ced 100644 --- a/webhooks/functions/src/model/storage.interface.ts +++ b/webhooks/functions/src/model/storage.interface.ts @@ -40,6 +40,7 @@ export interface ISessionScene { 'search': { state: TStateSearch, query: string, + from: TSdkHandler, } } export type TKeySessionScene = keyof ISessionScene; diff --git a/webhooks/functions/src/sdk/search.test.ts b/webhooks/functions/src/sdk/search.test.ts index 8cb1a1cd..ed3d1889 100644 --- a/webhooks/functions/src/sdk/search.test.ts +++ b/webhooks/functions/src/sdk/search.test.ts @@ -64,6 +64,24 @@ describe(scene + ' handler', () => { data.prompt.firstSimple.speech.should.to.be.eq(message); }); + it('on enter no query available and running', async () => { + body.handler.name = 'search__on_enter'; + body.scene.name = scene; + + const message = `In the meanwhile, is there another title or author you'd like to search for ?\n`; + + const pullData = parsedDataClone(); + + pullData.session.scene.search.query = ''; + pullData.session.scene.search.state = 'RUNNING'; + pullData.session.scene.search.from = 'selection__on_enter'; + + const model = await storageModelMocked(pullData); + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + model.data.store.session.scene.search.from.should.to.be.eq('main'); + }); it('on enter query and finish state', async () => { body.handler.name = 'search__on_enter'; body.scene.name = scene; diff --git a/webhooks/functions/src/sdk/selection.test.ts b/webhooks/functions/src/sdk/selection.test.ts index 568c9958..49967471 100644 --- a/webhooks/functions/src/sdk/selection.test.ts +++ b/webhooks/functions/src/sdk/selection.test.ts @@ -277,6 +277,63 @@ describe(scene + ' handler', () => { return {pullData, feed, message}; }; + it('on enter - state running - publication empty', async () => { + body.handler.name = 'selection__on_enter'; + body.scene.name = scene; + + let {pullData, feed, message} = testStateRunningPublication(); + pullData.session.scene.selection.nextUrlCounter = 0; + + // @ts-ignore + feed.publications = []; + + message = 'Uh Oh! Nothing to read here quite yet. Not to worry though, we can fix that right away! Would you like to browse our collections? Or perhaps you\'d like to search for a specific book by author or book title?\n'; + + const data = await expressMocked(body, headers, pullData, feed); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + // data.scene.next.name.should.to.be.eq('selection'); + }); + it('on enter - state running - group empty', async () => { + body.handler.name = 'selection__on_enter'; + body.scene.name = scene; + + let {pullData, feed, message} = testStateRunningGroup(); + pullData.session.scene.selection.nextUrlCounter = 0; + + // @ts-ignore + feed.groups = []; + + message = 'Uh Oh! Nothing to read here quite yet. Not to worry though, we can fix that right away! Would you like to browse our collections? Or perhaps you\'d like to search for a specific book by author or book title?\n'; + + const data = await expressMocked(body, headers, pullData, feed); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + // data.scene.next.name.should.to.be.eq('selection'); + }); + it('on enter - state running - publication empty - from search', async () => { + body.handler.name = 'selection__on_enter'; + body.scene.name = scene; + + let {pullData, feed, message} = testStateRunningPublication(); + pullData.session.scene.selection.nextUrlCounter = 0; + pullData.session.scene.selection.from = 'search__on_enter'; + const model = await storageModelMocked(pullData); + + // @ts-ignore + feed.publications = []; + + message = 'It seems like the book you are looking for is currently unavailable in the EDRLAB Library.\n'; + + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); + + data.prompt.firstSimple.speech.should.to.be.eq(message); + model.data.store.session.scene.search.from.should.to.be.eq('selection__on_enter'); + model.data.store.session.scene.search.query.should.to.be.eq(''); + model.data.store.session.scene.search.state.should.to.be.eq('RUNNING'); + data.scene.next.name.should.to.be.eq('search'); + }); + it('on enter - state running - publication list first page with no next link', async () => { body.handler.name = 'selection__on_enter'; body.scene.name = scene; diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index 356a3cb8..2e595073 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -72,7 +72,12 @@ }, "search": { "enter": { - "1": "What book or author are you looking for ?" + "1": "What book or author are you looking for ?", + "2": "In the meanwhile, is there another title or author you'd like to search for ?" + }, + "empty": { + "1": "It seems like the book you are looking for is currently unavailable in the {{- name}} Library.", + "2": "You can suggest books for us to add at {{- website}}." } }, "selection": { diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index aaaf08bb..8b683560 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "player.start" | "player.askResumeLastOffset" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", + "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "player.start" | "player.askResumeLastOffset" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:player.start" | "en:player.askResumeLastOffset" | "en:collections.enter.1" | "en:collections.help.1" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", + "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:search.enter.2" | "en:search.empty.1" | "en:search.empty.2" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:player.start" | "en:player.askResumeLastOffset" | "en:collections.enter.1" | "en:collections.help.1" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } From 881a534624e91d070a3a96d692564f5b26079cff Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 7 Mar 2022 16:41:07 +0100 Subject: [PATCH 154/180] sdk: add collections intent --- sdk/custom/intents/en/collections.yaml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 sdk/custom/intents/en/collections.yaml diff --git a/sdk/custom/intents/en/collections.yaml b/sdk/custom/intents/en/collections.yaml new file mode 100644 index 00000000..8ab286a5 --- /dev/null +++ b/sdk/custom/intents/en/collections.yaml @@ -0,0 +1,3 @@ +trainingPhrases: +- collections +- Browse collections From 419b58d3869ea68c14f2629ede07d38c618daa0c Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 8 Mar 2022 17:48:52 +0100 Subject: [PATCH 155/180] fix: selection handle groups selection --- .../functions/src/controller/Assistant.ts | 17 +- webhooks/functions/src/controller/Machine.ts | 20 +- .../src/controller/handler/selection.ts | 33 +-- webhooks/functions/src/sdk/selection.test.ts | 189 +++++++++++++++++- 4 files changed, 236 insertions(+), 23 deletions(-) diff --git a/webhooks/functions/src/controller/Assistant.ts b/webhooks/functions/src/controller/Assistant.ts index 3c518c90..edb84dee 100644 --- a/webhooks/functions/src/controller/Assistant.ts +++ b/webhooks/functions/src/controller/Assistant.ts @@ -4,6 +4,8 @@ import {PROJECT_ID} from '../constants'; import {StorageModel} from '../model/storage.model'; import {THandlerFn} from '../type'; import {TSdkHandler} from '../typings/sdkHandler'; +import {TSdkScene} from '../typings/sdkScene'; +import {enter as selectionEnter} from './handler/selection'; import {Machine} from './Machine'; export class Assistant { @@ -20,7 +22,7 @@ export class Assistant { }) { this._app = conversation({ verification: process.env['NODE_ENV'] === 'PRODUCTION' ? PROJECT_ID : undefined, - debug: false, + debug: process.env['NODE_ENV'] === 'development' ? true : false, }); this._app.catch((conv, error) => { @@ -53,14 +55,23 @@ export class Assistant { this._app.handle(path, async (conv) => { const machine = new Machine(conv); + console.info('ASSISTANT:', path); + console.info('scene.name=', conv.scene.name); + console.info('linkingStatus', conv.user.accountLinkingStatus); + const bearerToken = conv.user.params.bearerToken; await machine.begin({bearerToken, storageModel: this._storageModel, fetcher: this._fetcher}); await Promise.resolve(fn(machine)); - await machine.end(); + // HACK + // google actions platform doesn't allow to set the same next scene name than the actual in the 'on_enter' handler scene + // it's a platform limitation for a basic infinite loop I think + if (path === 'selection__intent__selects_book' && conv.scene.next?.name as TSdkScene === 'selection') { + await Promise.resolve(selectionEnter(machine)); + } - // console.log(JSON.stringify(conv, null, 4)); + await machine.end(); }); }; diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 5465591f..cc929d03 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -81,10 +81,14 @@ export class Machine { } } - public async say(key: TI18nKey, options?: object) { + public say(key: TI18nKey, options?: object) { this._sayAcc += this._i18n.t(key, options) + '\n'; } + public saidSomething(): boolean { + return !!this._sayAcc; + } + public get isLinked() { return this._conv.user.accountLinkingStatus; } @@ -162,6 +166,11 @@ export class Machine { return {title, author}; } + public debugSelectionSession() { + ok(this._model); + console.info(this._model.store.session.scene.selection); + } + public get selectionSession() { ok(this._model); return this._model.store.session.scene.selection; @@ -233,6 +242,9 @@ export class Machine { this.selectionSession.kind = 'PUBLICATION'; // set to publication mode this.selectionSession.nextUrlCounter = 0; // reset this.selectionSession.state = 'RUNNING'; + this.selectionSession.nbChoice = 0; // reset + + this.debugSelectionSession(); return true; } @@ -253,6 +265,12 @@ export class Machine { } this.initPlayerCurrentWithWebpubUrl(pub.webpubUrl); + this.selectionSession.state = 'DEFAULT'; + this.selectionSession.from = 'main'; + this.selectionSession.url = ''; + this.selectionSession.nbChoice = 0; // reset + this.selectionSession.nextUrlCounter = 0; // reset + return true; } return false; diff --git a/webhooks/functions/src/controller/handler/selection.ts b/webhooks/functions/src/controller/handler/selection.ts index 4528f553..27601557 100644 --- a/webhooks/functions/src/controller/handler/selection.ts +++ b/webhooks/functions/src/controller/handler/selection.ts @@ -17,11 +17,13 @@ export const selection = (app: Assistant) => { } -const enter: THandlerFn = async (m) => { +export const enter: THandlerFn = async (m) => { const { state, url, nbChoice } = m.selectionSession; const kind = m.selectionSession.kind; const handler = m.selectionSession.from; + + m.debugSelectionSession(); if (state === "RUNNING") { @@ -92,22 +94,29 @@ const enter: THandlerFn = async (m) => { if (valid) { // select OK - const { state } = m.selectionSession; - if (state === "RUNNING") { + const { state, kind } = m.selectionSession; + console.log("FINISH VALID STATE: ", state, kind); + + if (kind === "GROUP" && state === "RUNNING") { + console.log("RUN GROUPS"); // group requested m.nextScene = "selection"; - } - - // const handler = m.selectionSession.from; - // is it usefull ? - // routing table - // all 'handler from' route to player ? + } else if (kind === "PUBLICATION" && state === "RUNNING") { + console.log("RUN PUBLICATIONS"); - m.nextScene = "player"; - // @TODO set the next-scene to player prequel - // lecture en cours ou annonciation du titre + m.nextScene = "selection"; + } else if (state === "DEFAULT" && m.playerCurrent.playing) { + console.log("RUN PLAYER"); + m.nextScene = "player"; + // @TODO set the next-scene to player prequel + // lecture en cours ou annonciation du titre + } else { + throw new Error("indalid finish state " + state); + } + } else { + // KO // help message m.say("selection.help.1"); diff --git a/webhooks/functions/src/sdk/selection.test.ts b/webhooks/functions/src/sdk/selection.test.ts index 49967471..fd1db4d0 100644 --- a/webhooks/functions/src/sdk/selection.test.ts +++ b/webhooks/functions/src/sdk/selection.test.ts @@ -501,9 +501,13 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); - data.scene.next.name.should.to.be.eq('selection'); - model.data.store.session.scene.selection.state.should.to.be.eq('FINISH'); - model.data.store.session.scene.selection.nbChoice.should.to.be.eq(1); + data.scene.next.name.should.to.be.eq('player'); + model.data.store.session.scene.selection.state.should.to.be.eq('DEFAULT'); + model.data.store.session.scene.selection.url.should.to.be.eq(''); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); + model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(0); + model.data.store.session.scene.selection.from.should.to.be.eq('main'); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); }); it('select book - number 2 ', async () => { body.handler.name = 'selection__intent__selects_book'; @@ -524,9 +528,13 @@ describe(scene + ' handler', () => { feed.publications?.length.should.to.be.eq(2); const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); - data.scene.next.name.should.to.be.eq('selection'); - model.data.store.session.scene.selection.state.should.to.be.eq('FINISH'); - model.data.store.session.scene.selection.nbChoice.should.to.be.eq(2); + data.scene.next.name.should.to.be.eq('player'); + model.data.store.session.scene.selection.state.should.to.be.eq('DEFAULT'); + model.data.store.session.scene.selection.url.should.to.be.eq(''); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); + model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(0); + model.data.store.session.scene.selection.from.should.to.be.eq('main'); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); }); it('select book - number 3 with only 2 pub available', async () => { @@ -542,14 +550,41 @@ describe(scene + ' handler', () => { const pullData = parsedDataClone(); const model = await storageModelMocked(pullData); model.data.store.session.scene.selection.kind = 'PUBLICATION'; + model.data.store.session.scene.selection.state = 'RUNNING'; model.data.store.session.scene.selection.url = 'http://my.url'; const feed = newFeed(); feed.publications?.length.should.to.be.eq(2); const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); data.scene.next.name.should.to.be.eq('selection'); + model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); + }); + + it('select book - state == DEFAULT should throw', async () => { + body.handler.name = 'selection__intent__selects_book'; + body.scene.name = scene; + body.intent.params = { + number: { + original: '3', + resolved: 3, + }, + }; + + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + model.data.store.session.scene.selection.kind = 'PUBLICATION'; + model.data.store.session.scene.selection.url = 'http://my.url'; + const feed = newFeed(); + feed.publications?.length.should.to.be.eq(2); + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); + + // THROWS !! + + data.scene.next.name.should.to.be.eq('actions.scene.END_CONVERSATION'); model.data.store.session.scene.selection.state.should.to.be.eq('DEFAULT'); model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); + data.prompt.firstSimple.speech.should.to.be.eq('Oops, something went wrong. I will exit the app. Feel free to reopen it as soon as possible.'); }); it('select book - number 10', async () => { @@ -571,7 +606,147 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); data.scene.next.name.should.to.be.eq('selection'); - data.prompt.firstSimple.speech.should.to.be.eq(help); + data.prompt.firstSimple.speech.should.to.be.eq('Pick one out of 3 titles by mentioning their numbers. You can also ask for \'another one\'.\n' + + 'Pick one of these by saying their numbers.\n' + + '1. first publication\n' + + '2. second publication\n' + + 'Which one would you like to start reading?\n'); + model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); // equals to original state + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); // reset + // or + // say the fallback message if type is incorrect + // need to check with google data + }); + it('select book - group - number 1', async () => { + body.handler.name = 'selection__intent__selects_book'; + body.scene.name = scene; + body.intent.params = { + number: { + original: '1', + resolved: 1, + }, + }; + + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + model.data.store.session.scene.selection.kind = 'GROUP'; + model.data.store.session.scene.selection.state = 'RUNNING'; + model.data.store.session.scene.selection.url = 'http://my.url'; + const feed = newFeed(); + feed.publications?.length.should.to.be.eq(2); + + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); + + data.scene.next.name.should.to.be.eq('selection'); + model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); + model.data.store.session.scene.selection.url.should.to.be.eq('http://group.url'); + model.data.store.session.scene.selection.kind.should.to.be.eq('PUBLICATION'); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); + }); + it('select book - group - number 2', async () => { + body.handler.name = 'selection__intent__selects_book'; + body.scene.name = scene; + body.intent.params = { + number: { + original: '2', + resolved: 2, + }, + }; + + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + model.data.store.session.scene.selection.kind = 'GROUP'; + model.data.store.session.scene.selection.state = 'RUNNING'; + model.data.store.session.scene.selection.url = 'http://my.url'; + const feed = newFeed(); + feed.publications?.length.should.to.be.eq(2); + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); + + data.scene.next.name.should.to.be.eq('selection'); + model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); + model.data.store.session.scene.selection.url.should.to.be.eq('http://group.url'); + model.data.store.session.scene.selection.kind.should.to.be.eq('PUBLICATION'); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); + }); + + it('select book - group - number 3 with only 2 pub available', async () => { + body.handler.name = 'selection__intent__selects_book'; + body.scene.name = scene; + body.intent.params = { + number: { + original: '3', + resolved: 3, + }, + }; + + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + model.data.store.session.scene.selection.kind = 'GROUP'; + model.data.store.session.scene.selection.state = 'RUNNING'; + model.data.store.session.scene.selection.url = 'http://my.url'; + const feed = newFeed(); + feed.publications?.length.should.to.be.eq(2); + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); + + data.scene.next.name.should.to.be.eq('selection'); + data.prompt.firstSimple.speech.should.to.be.eq('Pick one out of 3 titles by mentioning their numbers. You can also ask for \'another one\'.\n' + + 'Pick one of these by saying their numbers.\n' + + '1. first group\n' + + '2. second group\n' + + 'Which one would you like to start reading?\n'); + model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); // equals to original state + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); // reset + }); + it('select book - group - state == DEFAULT should throw', async () => { + body.handler.name = 'selection__intent__selects_book'; + body.scene.name = scene; + body.intent.params = { + number: { + original: '3', + resolved: 3, + }, + }; + + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + model.data.store.session.scene.selection.kind = 'GROUP'; + model.data.store.session.scene.selection.url = 'http://my.url'; + const feed = newFeed(); + feed.publications?.length.should.to.be.eq(2); + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); + + // THROWS !! + + data.scene.next.name.should.to.be.eq('actions.scene.END_CONVERSATION'); + model.data.store.session.scene.selection.state.should.to.be.eq('DEFAULT'); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); + data.prompt.firstSimple.speech.should.to.be.eq('Oops, something went wrong. I will exit the app. Feel free to reopen it as soon as possible.'); + }); + + it('select book - group - number 10', async () => { + body.handler.name = 'selection__intent__selects_book'; + body.scene.name = scene; + body.intent.params = { + number: { + original: '10', + resolved: 10, + }, + }; + + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + model.data.store.session.scene.selection.url = 'http://my.url'; + model.data.store.session.scene.selection.state = 'RUNNING'; + model.data.store.session.scene.selection.kind = 'GROUP'; + const feed = newFeed(); + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); + + data.scene.next.name.should.to.be.eq('selection'); + data.prompt.firstSimple.speech.should.to.be.eq('Pick one out of 3 titles by mentioning their numbers. You can also ask for \'another one\'.\n' + + 'Pick one of these by saying their numbers.\n' + + '1. first group\n' + + '2. second group\n' + + 'Which one would you like to start reading?\n'); model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); // equals to original state model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); // reset // or From f88821cb86ac81aaf928b006961ba0b33946f22c Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 8 Mar 2022 18:05:07 +0100 Subject: [PATCH 156/180] Delete sdk-test-dev.yml --- .github/workflows/sdk-test-dev.yml | 39 ------------------------------ 1 file changed, 39 deletions(-) delete mode 100644 .github/workflows/sdk-test-dev.yml diff --git a/.github/workflows/sdk-test-dev.yml b/.github/workflows/sdk-test-dev.yml deleted file mode 100644 index 4df5018b..00000000 --- a/.github/workflows/sdk-test-dev.yml +++ /dev/null @@ -1,39 +0,0 @@ - -name: sdk test dev - -on: - push: - branches: [ develop ] - # paths: - # pull_request: - # branches: [ develop ] - paths: - - 'sdk/test/**' - - 'test/dev/**' - - '.github/workflows/sdk-test-dev.yml' - -jobs: - sdk-test-dev: - name: "Test sdk DEV" - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [14.x] - # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ - defaults: - run: - working-directory: './test' - - steps: - - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - - - name: save service_account - run: echo $SECRET >> service_account.json - env: - SECRET : ${{ secrets.SERVICE_ACCOUNT_VALENTIN5 }} - - run: npm install - - run: npm test From 8113b23d56bb26af30c55f8845d572cdc6a4228a Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 8 Mar 2022 18:06:04 +0100 Subject: [PATCH 157/180] Update functions-edrlab-dev.yml --- .github/workflows/functions-edrlab-dev.yml | 26 ---------------------- 1 file changed, 26 deletions(-) diff --git a/.github/workflows/functions-edrlab-dev.yml b/.github/workflows/functions-edrlab-dev.yml index d88207e5..374af269 100644 --- a/.github/workflows/functions-edrlab-dev.yml +++ b/.github/workflows/functions-edrlab-dev.yml @@ -69,29 +69,3 @@ jobs: env: FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} PROJECT_PATH: './webhooks' - - sdk-test-dev: - name: "Test sdk DEV" - needs: deploy - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [14.x] - # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ - defaults: - run: - working-directory: './test/dev' - - steps: - - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - - - name: save service_account - run: echo $SECRET >> service_account.json - env: - SECRET : ${{ secrets.SERVICE_ACCOUNT_VALENTIN5 }} - - run: npm install - - run: npm test From 966f6018cebedac20f64cbf59f494d09ac2a3e5e Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Tue, 8 Mar 2022 20:23:02 +0100 Subject: [PATCH 158/180] remove test online that is unused now --- test/.eslintrc.json | 20 - test/package-lock.json | 3094 ---------------------------------------- test/package.json | 26 - test/test/constant.ts | 18 - test/test/test1.ts | 44 - test/test/test10.ts | 58 - test/test/test11.ts | 58 - test/test/test12.ts | 67 - test/test/test13.ts | 60 - test/test/test2.ts | 57 - test/test/test3-2.ts | 74 - test/test/test3.ts | 63 - test/test/test4.ts | 258 ---- test/test/test5.ts | 221 --- test/test/test6.ts | 248 ---- test/test/test7.ts | 254 ---- test/test/test8.ts | 256 ---- test/test/test9.ts | 133 -- 18 files changed, 5009 deletions(-) delete mode 100644 test/.eslintrc.json delete mode 100644 test/package-lock.json delete mode 100644 test/package.json delete mode 100644 test/test/constant.ts delete mode 100644 test/test/test1.ts delete mode 100644 test/test/test10.ts delete mode 100644 test/test/test11.ts delete mode 100644 test/test/test12.ts delete mode 100644 test/test/test13.ts delete mode 100644 test/test/test2.ts delete mode 100644 test/test/test3-2.ts delete mode 100644 test/test/test3.ts delete mode 100644 test/test/test4.ts delete mode 100644 test/test/test5.ts delete mode 100644 test/test/test6.ts delete mode 100644 test/test/test7.ts delete mode 100644 test/test/test8.ts delete mode 100644 test/test/test9.ts diff --git a/test/.eslintrc.json b/test/.eslintrc.json deleted file mode 100644 index c5624c4e..00000000 --- a/test/.eslintrc.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "env": { - "browser": true, - "es2021": true - }, - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": 12, - "sourceType": "module" - }, - "plugins": [ - "@typescript-eslint" - ], - "rules": { - } -} diff --git a/test/package-lock.json b/test/package-lock.json deleted file mode 100644 index 3677cf9a..00000000 --- a/test/package-lock.json +++ /dev/null @@ -1,3094 +0,0 @@ -{ - "name": "lis-mon-livre-test", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@assistant/actions": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@assistant/actions/-/actions-0.1.0.tgz", - "integrity": "sha512-V3PUGj7j/8Gq4VPFwP40k6AnsJaV2nnViuGskYnCe8sKLgCTzeGsOKnoGJgEEjI3ETm5mPd8ym3/HoksRODMNw==", - "dev": true, - "requires": { - "google-gax": "^2.9.2" - } - }, - "@assistant/conversation-testing": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@assistant/conversation-testing/-/conversation-testing-1.0.0.tgz", - "integrity": "sha512-9NZ3q1PI/FXegVaF+Kt2M/z2tWcDSPZ8aQ/UBYqtmYk0xSQX3ZRNhg9FWEGeAGL7+1tV4aRRkBylTvUUOGivrQ==", - "dev": true, - "requires": { - "@assistant/actions": "0.1.0", - "@types/chai": "^4.1.4", - "@types/i18n": "^0.8.6", - "@types/js-yaml": "^3.12.5", - "@types/node": "^10.9.4", - "@types/promise.prototype.finally": "^2.0.3", - "chai": "^4.2.0", - "google-auth-library": "^6.1.2", - "grpc": "^1.24.0", - "i18n": "^0.8.3", - "js-yaml": "^3.14.0", - "promise.prototype.finally": "^3.1.1", - "ts-node": "^7.0.1" - }, - "dependencies": { - "@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - } - } - } - }, - "@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true - }, - "@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", - "dev": true, - "requires": { - "@cspotcode/source-map-consumer": "0.8.0" - } - }, - "@eslint/eslintrc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.3.tgz", - "integrity": "sha512-DHI1wDPoKCBPoLZA3qDR91+3te/wDSc1YhKg3jR8NxKKRJq2hwHwcWv31cSwSYvIBrmbENoYMWcenW8uproQqg==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.0.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - } - }, - "@grpc/grpc-js": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.4.1.tgz", - "integrity": "sha512-/chkA48TdAvATHA7RXJPeHQLdfFhpu51974s8htjO/XTDHA41j5+SkR5Io+lr9XsLmkZD6HxLyRAFGmA9wjO2w==", - "dev": true, - "requires": { - "@grpc/proto-loader": "^0.6.4", - "@types/node": ">=12.12.47" - } - }, - "@grpc/proto-loader": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.6.tgz", - "integrity": "sha512-cdMaPZ8AiFz6ua6PUbP+LKbhwJbFXnrQ/mlnKGUyzDUZ3wp7vPLksnmLCBX6SHgSmjX7CbNVNLFYD5GmmjO4GQ==", - "dev": true, - "requires": { - "@types/long": "^4.0.1", - "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", - "protobufjs": "^6.10.0", - "yargs": "^16.1.1" - } - }, - "@humanwhocodes/config-array": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.6.0.tgz", - "integrity": "sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", - "dev": true - }, - "@mapbox/node-pre-gyp": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.6.tgz", - "integrity": "sha512-qK1ECws8UxuPqOA8F5LFD90vyVU33W7N3hGfgsOVfrJaRVc8McC3JClTDHpeSbL9CBrOHly/4GsNPAvIgNZE+g==", - "dev": true, - "requires": { - "detect-libc": "^1.0.3", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.5", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=", - "dev": true - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "dev": true - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "dev": true - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=", - "dev": true - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "dev": true, - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=", - "dev": true - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=", - "dev": true - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=", - "dev": true - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=", - "dev": true - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", - "dev": true - }, - "@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", - "dev": true - }, - "@types/bytebuffer": { - "version": "5.0.42", - "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.42.tgz", - "integrity": "sha512-lEgKojWUAc/MG2t649oZS5AfYFP2xRNPoDuwDBlBMjHXd8MaGPgFgtCXUK7inZdBOygmVf10qxc1Us8GXC96aw==", - "dev": true, - "requires": { - "@types/long": "*", - "@types/node": "*" - } - }, - "@types/chai": { - "version": "4.2.22", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.22.tgz", - "integrity": "sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ==", - "dev": true - }, - "@types/i18n": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@types/i18n/-/i18n-0.8.8.tgz", - "integrity": "sha512-RI4LFAraGrimMTxXkediCMXGVLC6ksXIIo3U+d3E4n+Mhw3uIDbmokO7DHlPB/eu6Tn6KBv4IUE1WrrEDRdNUQ==", - "dev": true - }, - "@types/js-yaml": { - "version": "3.12.7", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.7.tgz", - "integrity": "sha512-S6+8JAYTE1qdsc9HMVsfY7+SgSuUU/Tp6TYTmITW0PZxiyIMvol3Gy//y69Wkhs0ti4py5qgR3uZH6uz/DNzJQ==", - "dev": true - }, - "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true - }, - "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==", - "dev": true - }, - "@types/mocha": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.0.0.tgz", - "integrity": "sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==", - "dev": true - }, - "@types/node": { - "version": "16.11.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.4.tgz", - "integrity": "sha512-TMgXmy0v2xWyuCSCJM6NCna2snndD8yvQF67J29ipdzMcsPa9u+o0tjF5+EQNdhcuZplYuouYqpc4zcd5I6amQ==", - "dev": true - }, - "@types/promise.prototype.finally": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/promise.prototype.finally/-/promise.prototype.finally-2.0.4.tgz", - "integrity": "sha512-bkzsMz11tGI5r/ZhJIVI1+QSWKKBcX/Llv0zoM2ufOH+o/3sLXwE5xCW0OUX81xPa4EGOyPKFlNrH9GH+IF4lg==", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.1.0.tgz", - "integrity": "sha512-bekODL3Tqf36Yz8u+ilha4zGxL9mdB6LIsIoMAvvC5FAuWo4NpZYXtCbv7B2CeR1LhI/lLtLk+q4tbtxuoVuCg==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "5.1.0", - "@typescript-eslint/scope-manager": "5.1.0", - "debug": "^4.3.2", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.2.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - } - } - }, - "@typescript-eslint/experimental-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.1.0.tgz", - "integrity": "sha512-ovE9qUiZMOMgxQAESZsdBT+EXIfx/YUYAbwGUI6V03amFdOOxI9c6kitkgRvLkJaLusgMZ2xBhss+tQ0Y1HWxA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.1.0", - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/typescript-estree": "5.1.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "dependencies": { - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - } - } - }, - "@typescript-eslint/parser": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.1.0.tgz", - "integrity": "sha512-vx1P+mhCtYw3+bRHmbalq/VKP2Y3gnzNgxGxfEWc6OFpuEL7iQdAeq11Ke3Rhy8NjgB+AHsIWEwni3e+Y7djKA==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.1.0", - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/typescript-estree": "5.1.0", - "debug": "^4.3.2" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.1.0.tgz", - "integrity": "sha512-yYlyVjvn5lvwCL37i4hPsa1s0ORsjkauhTqbb8MnpvUs7xykmcjGqwlNZ2Q5QpoqkJ1odlM2bqHqJwa28qV6Tw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/visitor-keys": "5.1.0" - } - }, - "@typescript-eslint/types": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.1.0.tgz", - "integrity": "sha512-sEwNINVxcB4ZgC6Fe6rUyMlvsB2jvVdgxjZEjQUQVlaSPMNamDOwO6/TB98kFt4sYYfNhdhTPBEQqNQZjMMswA==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.1.0.tgz", - "integrity": "sha512-SSz+l9YrIIsW4s0ZqaEfnjl156XQ4VRmJsbA0ZE1XkXrD3cRpzuZSVCyqeCMR3EBjF27IisWakbBDGhGNIOvfQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/visitor-keys": "5.1.0", - "debug": "^4.3.2", - "globby": "^11.0.4", - "is-glob": "^4.0.3", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.1.0.tgz", - "integrity": "sha512-uqNXepKBg81JVwjuqAxYrXa1Ql/YDzM+8g/pS+TCPxba0wZttl8m5DkrasbfnmJGHs4lQ2jTbcZ5azGhI7kK+w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.1.0", - "eslint-visitor-keys": "^3.0.0" - } - }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true - }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "dev": true - }, - "are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - }, - "dependencies": { - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - } - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true - }, - "ascli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", - "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", - "dev": true, - "requires": { - "colour": "~0.7.1", - "optjs": "~3.2.2" - } - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", - "dev": true - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=", - "dev": true - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "bytebuffer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", - "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", - "dev": true, - "requires": { - "long": "~3" - }, - "dependencies": { - "long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", - "dev": true - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, - "colour": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz", - "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "dev": true, - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.1.0.tgz", - "integrity": "sha512-JZvNneArGSUsluHWJ8g8MMs3CfIEzwaLx9KyH4tZ2i+R2/rPWzL8c0zg3rHdwYVpN/1sB9gqnjHwz9HoeJpGHw==", - "dev": true, - "requires": { - "@eslint/eslintrc": "^1.0.3", - "@humanwhocodes/config-array": "^0.6.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^6.0.0", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.0.0", - "espree": "^9.0.0", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.2.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - } - } - }, - "eslint-scope": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-6.0.0.tgz", - "integrity": "sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz", - "integrity": "sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q==", - "dev": true - }, - "espree": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.0.0.tgz", - "integrity": "sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ==", - "dev": true, - "requires": { - "acorn": "^8.5.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.0.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fast-text-encoding": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", - "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==", - "dev": true - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", - "dev": true - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "gauge": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.1.tgz", - "integrity": "sha512-6STz6KdQgxO4S/ko+AbjlFGGdGcknluoqU+79GOFCDqqyYj5OanQf9AjxwN0jCidtT+ziPMmPSt9E4hfQ0CwIQ==", - "dev": true, - "requires": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1 || ^2.0.0", - "strip-ansi": "^3.0.1 || ^4.0.0", - "wide-align": "^1.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "gaxios": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.2.tgz", - "integrity": "sha512-T+ap6GM6UZ0c4E6yb1y/hy2UB6hTrqhglp3XfmU9qbLCGRYhLVV5aRPpC4EmoG8N8zOnkYCgoBz+ScvGAARY6Q==", - "dev": true, - "requires": { - "abort-controller": "^3.0.0", - "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.1" - } - }, - "gcp-metadata": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.1.tgz", - "integrity": "sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==", - "dev": true, - "requires": { - "gaxios": "^4.0.0", - "json-bigint": "^1.0.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "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" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - } - } - }, - "google-auth-library": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.6.tgz", - "integrity": "sha512-Q+ZjUEvLQj/lrVHF/IQwRo6p3s8Nc44Zk/DALsN+ac3T4HY/g/3rrufkgtl+nZ1TW7DNAw5cTChdVp4apUXVgQ==", - "dev": true, - "requires": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - } - }, - "google-gax": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.28.0.tgz", - "integrity": "sha512-kuqc8a4+CTCMBcF3tlOL7Sa74JWkTzcZxatAQTCVK35WToXkHnJ0qncFOJuegUv3EbV9IQY4j/+NZdFLv+lbTA==", - "dev": true, - "requires": { - "@grpc/grpc-js": "~1.4.0", - "@grpc/proto-loader": "^0.6.1", - "@types/long": "^4.0.0", - "abort-controller": "^3.0.0", - "duplexify": "^4.0.0", - "fast-text-encoding": "^1.0.3", - "google-auth-library": "^7.6.1", - "is-stream-ended": "^0.1.4", - "node-fetch": "^2.6.1", - "object-hash": "^2.1.1", - "proto3-json-serializer": "^0.1.1", - "protobufjs": "6.11.2", - "retry-request": "^4.0.0" - }, - "dependencies": { - "google-auth-library": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.10.1.tgz", - "integrity": "sha512-nQxgM1ZopUMcpMnu95kOSzI+9tJl4YDOZJomSTBGlRLpxfBopdwto7WvzoI87HuN0nQqVETgOsHi/C/po1rppA==", - "dev": true, - "requires": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - } - } - } - }, - "google-p12-pem": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.2.tgz", - "integrity": "sha512-tjf3IQIt7tWCDsa0ofDQ1qqSCNzahXDxdAGJDbruWqu3eCg5CKLYKN+hi0s6lfvzYZ1GDVr+oDF9OOWlDSdf0A==", - "dev": true, - "requires": { - "node-forge": "^0.10.0" - } - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "grpc": { - "version": "1.24.11", - "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.24.11.tgz", - "integrity": "sha512-8/AQdFCzCeCDWW3SoaMNp6ccbRvTQEH1O1u1uFtt29eWsg5gSZCJ3m6fbkduEIh3smY7WAPP+LgVJ5n3nZRxcA==", - "dev": true, - "requires": { - "@mapbox/node-pre-gyp": "^1.0.4", - "@types/bytebuffer": "^5.0.40", - "lodash.camelcase": "^4.3.0", - "lodash.clone": "^4.5.0", - "nan": "^2.13.2", - "protobufjs": "^5.0.3" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "protobufjs": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz", - "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==", - "dev": true, - "requires": { - "ascli": "~1", - "bytebuffer": "~5", - "glob": "^7.0.5", - "yargs": "^3.10.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", - "dev": true, - "requires": { - "camelcase": "^2.0.1", - "cliui": "^3.0.3", - "decamelize": "^1.1.1", - "os-locale": "^1.4.0", - "string-width": "^1.0.1", - "window-size": "^0.1.4", - "y18n": "^3.2.0" - } - } - } - }, - "gtoken": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.3.1.tgz", - "integrity": "sha512-yqOREjzLHcbzz1UrQoxhBtpk8KjrVhuqPE7od1K2uhyxG2BHjKZetlbLw/SPZak/QqTIQW+addS+EcjqQsZbwQ==", - "dev": true, - "requires": { - "gaxios": "^4.0.0", - "google-p12-pem": "^3.0.3", - "jws": "^4.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "i18n": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/i18n/-/i18n-0.8.6.tgz", - "integrity": "sha512-aMsJq8i1XXrb+BBsgmJBwak9mr69zPEIAUPb6c5yw2G/O4k1Q52lBxL+agZdQDN/RGf1ylQzrCswsOOgIiC1FA==", - "dev": true, - "requires": { - "debug": "*", - "make-plural": "^6.0.1", - "math-interval-parser": "^2.0.1", - "messageformat": "^2.3.0", - "mustache": "*", - "sprintf-js": "^1.1.2" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "is-stream-ended": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", - "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==", - "dev": true - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "is-weakref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "dev": true, - "requires": { - "bignumber.js": "^9.0.0" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "dev": true, - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "dev": true, - "requires": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", - "dev": true - }, - "lodash.clone": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", - "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "make-plural": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-6.2.2.tgz", - "integrity": "sha512-8iTuFioatnTTmb/YJjywkVIHLjcwkFD9Ms0JpxjEm9Mo8eQYkh1z+55dwv4yc1jQ8ftVBxWQbihvZL1DfzGGWA==", - "dev": true - }, - "math-interval-parser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/math-interval-parser/-/math-interval-parser-2.0.1.tgz", - "integrity": "sha512-VmlAmb0UJwlvMyx8iPhXUDnVW1F9IrGEd9CIOmv+XL8AErCUUuozoDMrgImvnYt2A+53qVX/tPW6YJurMKYsvA==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "messageformat": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/messageformat/-/messageformat-2.3.0.tgz", - "integrity": "sha512-uTzvsv0lTeQxYI2y1NPa1lItL5VRI8Gb93Y2K2ue5gBPyrbJxfDi/EYWxh2PKv5yO42AJeeqblS9MJSh/IEk4w==", - "dev": true, - "requires": { - "make-plural": "^4.3.0", - "messageformat-formatters": "^2.0.1", - "messageformat-parser": "^4.1.2" - }, - "dependencies": { - "make-plural": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz", - "integrity": "sha512-xTYd4JVHpSCW+aqDof6w/MebaMVNTVYBZhbB/vi513xXdiPT92JMVCo0Jq8W2UZnzYRFeVbQiQ+I25l13JuKvA==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - } - } - }, - "messageformat-formatters": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/messageformat-formatters/-/messageformat-formatters-2.0.1.tgz", - "integrity": "sha512-E/lQRXhtHwGuiQjI7qxkLp8AHbMD5r2217XNe/SREbBlSawe0lOqsFb7rflZJmlQFSULNLIqlcjjsCPlB3m3Mg==", - "dev": true - }, - "messageformat-parser": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-4.1.3.tgz", - "integrity": "sha512-2fU3XDCanRqeOCkn7R5zW5VQHWf+T3hH65SzuqRvjatBK7r4uyFa5mEX+k6F9Bd04LVM5G4/BHBTUJsOdW7uyg==", - "dev": true - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "minipass": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", - "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "mocha": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz", - "integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==", - "dev": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.2", - "debug": "4.3.2", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.7", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "nanoid": "3.1.25", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.1.5", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "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-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "mustache": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", - "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", - "dev": true - }, - "nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "dev": true - }, - "nanoid": { - "version": "3.1.25", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", - "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node-fetch": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", - "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", - "dev": true - }, - "nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "dev": true, - "requires": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", - "dev": true - }, - "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "optjs": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", - "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=", - "dev": true - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "promise.prototype.finally": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/promise.prototype.finally/-/promise.prototype.finally-3.1.3.tgz", - "integrity": "sha512-EXRF3fC9/0gz4qkt/f5EP5iW4kj9oFpBICNpCNOb/52+8nlHIX07FPLbi/q4qYBQ1xZqivMzTpNQSnArVASolQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "proto3-json-serializer": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-0.1.4.tgz", - "integrity": "sha512-bFzdsKU/zaTobWrRxRniMZIzzcgKYlmBWL1gAcTXZ2M7TQTGPI0JoYYs6bN7tpWj59ZCfwg7Ii/A2e8BbQGYnQ==", - "dev": true - }, - "protobufjs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", - "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", - "dev": true, - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "retry-request": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.2.2.tgz", - "integrity": "sha512-xA93uxUD/rogV7BV59agW/JHPGXeREMWiZc9jhcwY4YdZ7QOtC7qbomYg0n4wyk2lJhggjvKvhNX8wln/Aldhg==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "extend": "^3.0.2" - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "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 - }, - "source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true - }, - "ts-node": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", - "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "0.7.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "yn": "3.1.1" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - } - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dev": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", - "dev": true - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "workerpool": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", - "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "dependencies": { - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - } - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } - } -} diff --git a/test/package.json b/test/package.json deleted file mode 100644 index 62eccfc8..00000000 --- a/test/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "lis-mon-livre-test", - "version": "1.0.0", - "description": "", - "private": true, - "scripts": { - "lint": "eslint \"test/*.ts\"", - "enable-activity-controls": "env GOOGLE_APPLICATION_CREDENTIALS=$PWD/service_account.json web-and-app-activity-controls", - "test": "npm run lint && env GOOGLE_APPLICATION_CREDENTIALS=$PWD/service_account.json PROJECT_ID=$(cat $PWD/service_account.json| jq -r '.project_id') mocha --recursive --require ts-node/register test/*.ts", - "test:file": "npm run lint && env GOOGLE_APPLICATION_CREDENTIALS=$PWD/service_account.json PROJECT_ID=$(cat $PWD/service_account.json| jq -r '.project_id') mocha --recursive --require ts-node/register" - }, - "author": "", - "license": "ISC", - "devDependencies": { - "@assistant/conversation-testing": "^1.0.0", - "@types/mocha": "^9.0.0", - "@types/node": "^16.11.4", - "@typescript-eslint/eslint-plugin": "^5.1.0", - "@typescript-eslint/parser": "^5.1.0", - "chai": "^4.3.4", - "eslint": "^8.1.0", - "mocha": "^9.1.3", - "ts-node": "^10.4.0", - "typescript": "^4.4.4" - } -} diff --git a/test/test/constant.ts b/test/test/constant.ts deleted file mode 100644 index bba04e70..00000000 --- a/test/test/constant.ts +++ /dev/null @@ -1,18 +0,0 @@ - -import {env} from 'process'; -import {ok} from 'assert'; - -export const DEFAULT_LOCALE = 'fr-FR'; -export const DEFAULT_SURFACE = 'PHONE'; -export const HOME_PROMPT = "Bienvenue dans Valentin Audio."; -export const MEMBER_PROMPT = "Les commandes possibles sont: sélection, lecture, recherche. Que voulez-vous faire ?"; - -export const PROJECT_ID = env['PROJECT_ID'] || ''; -export const TRIGGER_PHRASE = 'Parler avec valentin audio dev'; - - -console.log(`PROJECT_ID=${PROJECT_ID}`); - -ok(PROJECT_ID, 'no PROJECT_ID'); - - diff --git a/test/test/test1.ts b/test/test/test1.ts deleted file mode 100644 index fe7185ed..00000000 --- a/test/test/test1.ts +++ /dev/null @@ -1,44 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; - -const TEST_NUM = 1; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('trigger only', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/test/test10.ts b/test/test/test10.ts deleted file mode 100644 index df8d7c46..00000000 --- a/test/test/test10.ts +++ /dev/null @@ -1,58 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as chai from 'chai'; - -const TEST_NUM = 10; -import * as fs from 'fs'; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - - await test.sendQuery(`sélections`); - test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre. Que voulez-vous faire ?`); - - await test.sendQuery(`selections thématiques`); - test.assertSpeech(`J'ai trouvé 2 sélections.\nnuméro 1 : liste d'essai de Philosophie.\nnuméro 2 : liste de l'auteur Emile Zola.\n\nPour choisir une sélection, dites son numéro.`); - - await test.sendQuery(`numéro 2`); - - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('thematic selection', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/test/test11.ts b/test/test/test11.ts deleted file mode 100644 index fcee609e..00000000 --- a/test/test/test11.ts +++ /dev/null @@ -1,58 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as chai from 'chai'; - -const TEST_NUM = 11; -import * as fs from 'fs'; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - - await test.sendQuery(`sélections`); - test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre. Que voulez-vous faire ?`); - - await test.sendQuery(`selections par genre`); - - test.assertSpeech(`J'ai trouvé 2 sélections.\nnuméro 1 : liste d'essai de Philosophie.\nnuméro 2 : roman.\n\nPour choisir une sélection, dites son numéro.`); - - await test.sendQuery(`numéro 2`); - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('genre selection', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/test/test12.ts b/test/test/test12.ts deleted file mode 100644 index f627359d..00000000 --- a/test/test/test12.ts +++ /dev/null @@ -1,67 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as fs from 'fs'; -import * as chai from 'chai'; - -const TEST_NUM = 12; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // RECHERCHE - - await test.sendQuery('recherche'); - - test.assertSpeech(`Que voulez-vous écouter ?`); - - await test.sendQuery('zola'); - - await test.assertSpeech(`J'ai trouvé 2 publications.\nnuméro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n`); - - await test.sendQuery('0'); - - await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. J'ai trouvé 2 publications.\nnuméro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n`); - - test.assertScene('select_publication'); - - await test.sendQuery('revenir au menu principal'); - - test.assertSpeech(MEMBER_PROMPT); - - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('search with zola query bad number choice and then stop it', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/test/test13.ts b/test/test/test13.ts deleted file mode 100644 index 9d1ad327..00000000 --- a/test/test/test13.ts +++ /dev/null @@ -1,60 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as chai from 'chai'; - -const TEST_NUM = 13; -import * as fs from 'fs'; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - - await test.sendQuery(`sélections`); - test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre. Que voulez-vous faire ?`); - - await test.sendQuery(`selections par genre`); - - test.assertSpeech(``); - - await test.sendQuery(`revenir au menu principal`); - - test.assertSpeech(MEMBER_PROMPT); - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('genre selection then stop', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/test/test2.ts b/test/test/test2.ts deleted file mode 100644 index 68eb2dcc..00000000 --- a/test/test/test2.ts +++ /dev/null @@ -1,57 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; - -const TEST_NUM = 2; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // RECHERCHE - - await test.sendQuery('recherche'); - - test.assertSpeech(`Que voulez-vous écouter ?`); - - await test.sendQuery('test avec aucune publication renvoyées'); - - await test.assertSpeech(`Aucun résultat trouvé. Que voulez-vous écouter ? Par exemple Zola.`); - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('search with bad query', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/test/test3-2.ts b/test/test/test3-2.ts deleted file mode 100644 index a36d4818..00000000 --- a/test/test/test3-2.ts +++ /dev/null @@ -1,74 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; - -const TEST_NUM = 302; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // RECHERCHE - - await test.sendQuery('recherche'); - - test.assertSpeech(`Que voulez-vous écouter ?`); - - await test.sendQuery('*'); - - test.assertSpeech(`J'ai trouvé 8 publications.\nVous êtes sur la page 1.\nnuméro 1 : vingt mille lieu sous les mers de Jule Verne.\nnuméro 2 : La chevre de monsieur segin de Alphonse Daudet.\nnuméro 3 : peau d'âne de Charles Perrault.\nnuméro 4 : Thérèse Raquin de Emile Zola.\nnuméro 5 : Du contrat social de Rousseau.\n\nPour choisir l'une des publications, dites son numéro.`); - - await test.sendQuery('0'); - - test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. J'ai trouvé 8 publications.\nVous êtes sur la page 1.\nnuméro 1 : vingt mille lieu sous les mers de Jule Verne.\nnuméro 2 : La chevre de monsieur segin de Alphonse Daudet.\nnuméro 3 : peau d'âne de Charles Perrault.\nnuméro 4 : Thérèse Raquin de Emile Zola.\nnuméro 5 : Du contrat social de Rousseau.\n\nPour choisir l'une des publications, dites son numéro.`); - - await test.sendQuery('suivant'); - - test.assertSpeech("Vous êtes sur la page 2.\nnuméro 1 : la guerre des boutons de pergaud.\nnuméro 2 : le prince de Nicolas Machiavel.\nnuméro 3 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n"); - - await test.sendQuery('suivant'); - - test.assertSpeech("Il n'y a pas de page suivante, je vais répéter la dernière page. Vous êtes sur la page 2.\nnuméro 1 : la guerre des boutons de pergaud.\nnuméro 2 : le prince de Nicolas Machiavel.\nnuméro 3 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n"); - - await test.sendQuery('repete'); - - test.assertSpeech("Vous êtes sur la page 2.\nnuméro 1 : la guerre des boutons de pergaud.\nnuméro 2 : le prince de Nicolas Machiavel.\nnuméro 3 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n"); - - test.assertScene('select_publication'); - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('search with zola query', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/test/test3.ts b/test/test/test3.ts deleted file mode 100644 index 720aacec..00000000 --- a/test/test/test3.ts +++ /dev/null @@ -1,63 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; - -const TEST_NUM = 3; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // RECHERCHE - - await test.sendQuery('recherche'); - - test.assertSpeech(`Que voulez-vous écouter ?`); - - await test.sendQuery('zola'); - - await test.assertSpeech(`J'ai trouvé 2 publications.\nnuméro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n`); - - await test.sendQuery('0'); - - await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. J'ai trouvé 2 publications.\nnuméro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n`); - - test.assertScene('select_publication'); - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('search with zola query', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/test/test4.ts b/test/test/test4.ts deleted file mode 100644 index 1424aa0d..00000000 --- a/test/test/test4.ts +++ /dev/null @@ -1,258 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as fs from 'fs'; -import * as chai from 'chai'; - -const TEST_NUM = 4; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // RECHERCHE - - await test.sendQuery('recherche'); - - test.assertSpeech(`Que voulez-vous écouter ?`); - - await test.sendQuery('zola'); - - await test.assertSpeech(`J'ai trouvé 2 publications.\nnuméro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n`); - - await test.sendQuery('0'); - - await test.assertSpeech(`Le numéro 0 est inconnu. Veuillez choisir un autre numéro. J'ai trouvé 2 publications.\nnuméro 1 : Thérèse Raquin de Emile Zola.\nnuméro 2 : L'assommoir de Emile Zola.\n\nPour choisir l'une des publications, dites son numéro.\n`); - - test.assertScene('select_publication'); - - await test.sendQuery('1'); - - const resp: any = test.getLatestResponse(); - - // console.log(resp); - // console.log(inspect(resp, {showHidden: false, depth: null, colors: true})); - // - - chai.expect(JSON.stringify(resp.output.actionsBuilderPrompt.content)).to.equal(JSON.stringify({ - "media": { - "optionalMediaControls": [ - "PAUSED", - "STOPPED" - ], - "mediaObjects": [ - { - "name": "Thérèse Raquin - 1", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap01-03.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 2", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap04-06.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 3", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap07-09.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 4", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap10-12.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 5", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap13-16.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 6", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap17-18.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 7", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap19-20.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 8", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap21-22.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 9", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap23-25.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 10", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap26-27.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 11", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap28-29.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 12", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap30-32.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - } - ], - "startOffset": { - "seconds": "0", - "nanos": 0 - }, - "mediaType": "AUDIO" - }, - "content": "media" - })); - - test.assertScene('player'); - - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('search with zola query bad number choice', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/test/test5.ts b/test/test/test5.ts deleted file mode 100644 index e2157e32..00000000 --- a/test/test/test5.ts +++ /dev/null @@ -1,221 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as chai from 'chai'; - -const TEST_NUM = 5; -import * as fs from 'fs'; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // 123 : player therese_raquin_emile_zola.json - await test.sendQuery(`test player 123`); - test.assertSpeech(`test player 123 ${MEMBER_PROMPT}`); - - // RECHERCHE - - await test.sendQuery('lecture'); - test.assertSpeech(`Voulez-vous reprendre la lecture là où elle s'était arrêtée ?`); - - await test.sendQuery('oui'); - - // console.log(test.getLatestResponse()); - - const media = test.getMedia(); - - // console.log(media); - - chai.expect(media).to.deep.equal({ - "optionalMediaControls": [ - "PAUSED", - "STOPPED" - ], - "mediaObjects": [ - { - "name": "Thérèse Raquin - 3", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap07-09.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 4", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap10-12.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 5", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap13-16.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 6", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap17-18.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 7", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap19-20.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 8", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap21-22.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 9", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap23-25.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 10", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap26-27.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 11", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap28-29.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 12", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap30-32.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - } - ], - "startOffset": { - "seconds": "123", - "nanos": 0 - }, - "mediaType": "AUDIO" - }); - - - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('remaining playing', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/test/test6.ts b/test/test/test6.ts deleted file mode 100644 index f7285132..00000000 --- a/test/test/test6.ts +++ /dev/null @@ -1,248 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as chai from 'chai'; - -const TEST_NUM = 6; -import * as fs from 'fs'; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // 123 : player therese_raquin_emile_zola.json - await test.sendQuery(`test player 123`); - test.assertSpeech(`test player 123 ${MEMBER_PROMPT}`); - - // RECHERCHE - - await test.sendQuery('lecture'); - test.assertSpeech(`Voulez-vous reprendre la lecture là où elle s'était arrêtée ?`); - // console.log(test.getLatestResponse()); - - await test.sendQuery('non'); - const media = test.getMedia(); - - // console.log(media); - -// fs.writeFileSync('/tmp/media.json', JSON.stringify(media)); - chai.expect(media).to.deep.equal({ - "optionalMediaControls": [ - "PAUSED", - "STOPPED" - ], - "mediaObjects": [ - { - "name": "Thérèse Raquin - 1", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap01-03.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 2", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap04-06.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 3", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap07-09.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 4", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap10-12.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 5", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap13-16.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 6", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap17-18.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 7", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap19-20.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 8", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap21-22.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 9", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap23-25.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 10", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap26-27.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 11", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap28-29.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 12", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap30-32.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - } - ], - "startOffset": { - "seconds": "0", - "nanos": 0 - }, - "mediaType": "AUDIO" - }); - - - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('playing from beginning', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/test/test7.ts b/test/test/test7.ts deleted file mode 100644 index 6d8825dd..00000000 --- a/test/test/test7.ts +++ /dev/null @@ -1,254 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as chai from 'chai'; - -const TEST_NUM = 7; -import * as fs from 'fs'; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // 123 : player therese_raquin_emile_zola.json - await test.sendQuery(`test player 123`); - test.assertSpeech(`test player 123 ${MEMBER_PROMPT}`); - - // RECHERCHE - - await test.sendQuery('lecture'); - test.assertSpeech(`Voulez-vous reprendre la lecture là où elle s'était arrêtée `); - - await test.sendQuery('test'); - const resp = test.getLatestResponse(); - chai.expect(test.getSpeech()).to.equal("je n'ai pas compris. Que voulez-vous dire ?"); - test.assertSpeech("je n'ai pas compris. Que voulez-vous dire ?"); - - let media = test.getMedia(); - chai.expect(media).to.equal(undefined); - - await test.sendQuery('non'); - - - media = test.getMedia(); -// fs.writeFileSync('/tmp/media.json', JSON.stringify(media)); - chai.expect(media).to.deep.equal({ - "optionalMediaControls": [ - "PAUSED", - "STOPPED" - ], - "mediaObjects": [ - { - "name": "Thérèse Raquin - 1", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap01-03.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 2", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap04-06.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 3", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap07-09.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 4", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap10-12.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 5", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap13-16.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 6", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap17-18.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 7", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap19-20.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 8", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap21-22.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 9", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap23-25.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 10", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap26-27.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 11", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap28-29.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 12", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap30-32.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - } - ], - "startOffset": { - "seconds": "0", - "nanos": 0 - }, - "mediaType": "AUDIO" - }); - - - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('playing bad yes or no', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/test/test8.ts b/test/test/test8.ts deleted file mode 100644 index a2c27d76..00000000 --- a/test/test/test8.ts +++ /dev/null @@ -1,256 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as chai from 'chai'; - -const TEST_NUM = 8; -import * as fs from 'fs'; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - // 123 : player therese_raquin_emile_zola.json - await test.sendQuery(`test player 123`); - test.assertSpeech(`test player 123 ${MEMBER_PROMPT}`); - - // RECHERCHE - - await test.sendQuery('lecture'); - test.assertSpeech(`Voulez-vous reprendre la lecture là où elle s'était arrêtée `); - - await test.sendQuery('non'); - - const media = test.getMedia(); -// fs.writeFileSync('/tmp/media.json', JSON.stringify(media)); - chai.expect(media).to.deep.equal({ - "optionalMediaControls": [ - "PAUSED", - "STOPPED" - ], - "mediaObjects": [ - { - "name": "Thérèse Raquin - 1", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap01-03.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 2", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap04-06.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 3", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap07-09.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 4", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap10-12.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 5", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap13-16.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 6", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap17-18.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 7", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap19-20.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 8", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap21-22.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 9", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap23-25.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 10", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap26-27.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 11", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap28-29.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Thérèse Raquin - 12", - "description": "", - "url": "https://archive.org/download/Therese-Raquin/Therese-Raquin-Chap30-32.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/a/a1/Raquin.jpg", - "alt": "Thérèse Raquin", - "height": 0, - "width": 0 - }, - "image": "large" - } - } - ], - "startOffset": { - "seconds": "0", - "nanos": 0 - }, - "mediaType": "AUDIO" - }); - - // await test.sendQuery('reprend la lecture'); - - // media = test.getMedia(); - // console.log(media); - - // // media === undefined - // // test doesn't handle intent during media playing - // // It's a TEST LIMITATION - // // - // // same - // chai.expect(media).to.equal(undefined); - - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({projectId: PROJECT_ID}); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('player resume listening | repprendre la lecture', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); diff --git a/test/test/test9.ts b/test/test/test9.ts deleted file mode 100644 index f5fbed22..00000000 --- a/test/test/test9.ts +++ /dev/null @@ -1,133 +0,0 @@ -import 'mocha'; - -import {ActionsOnGoogleTestManager} from '@assistant/conversation-testing'; -import {ok} from 'assert'; -import { inspect } from 'util'; -import { DEFAULT_LOCALE, DEFAULT_SURFACE, HOME_PROMPT, MEMBER_PROMPT, PROJECT_ID, TRIGGER_PHRASE } from './constant'; -import * as chai from 'chai'; - -const TEST_NUM = 9; -import * as fs from 'fs'; - -describe('My Action Test Suite', function () { - // Set the timeout for each test run to 60s. - this.timeout(60000); - let test: ActionsOnGoogleTestManager; - - async function startConversation() { - await test.sendQuery(TRIGGER_PHRASE); - test.assertSpeech(HOME_PROMPT + " " + MEMBER_PROMPT); - // test.assertText(HOME_PROMPT + " " + MEMBER_PROMPT); - test.assertIntent('actions.intent.MAIN'); - test.assertScene('home_members_lvl2'); - - await test.sendQuery(`setup test ${TEST_NUM}`); - test.assertSpeech(`setup test ${TEST_NUM} ${MEMBER_PROMPT}`); - - - await test.sendQuery(`sélections`); - test.assertSpeech(`Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre. Que voulez-vous faire ?`); - - await test.sendQuery(`ma liste`); - test.assertSpeech(`numéro 1 : L'assommoir de Emile Zola.\nnuméro 2 : Du contrat social de Rousseau.\n\nPour choisir l'une des publications, dites son numéro.\n`); - - await test.sendQuery(`2`); - - const media = test.getMedia(); - // fs.writeFileSync('/tmp/media.json', JSON.stringify(media)); - chai.expect(media).to.deep.equal({ - "optionalMediaControls": [ - "PAUSED", - "STOPPED" - ], - "mediaObjects": [ - { - "name": "Du contrat social - 1", - "description": "", - "url": "https://archive.org/download/Du-contrat-social/Du_contrat_social_livre1.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/d/db/Social_contract_rousseau_page.jpg", - "alt": "Du contrat social", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Du contrat social - 2", - "description": "", - "url": "https://archive.org/download/Du-contrat-social/Du_contrat_social_livre2.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/d/db/Social_contract_rousseau_page.jpg", - "alt": "Du contrat social", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Du contrat social - 3", - "description": "", - "url": "https://archive.org/download/Du-contrat-social/Du_contrat_social_livre3.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/d/db/Social_contract_rousseau_page.jpg", - "alt": "Du contrat social", - "height": 0, - "width": 0 - }, - "image": "large" - } - }, - { - "name": "Du contrat social - 4", - "description": "", - "url": "https://archive.org/download/Du-contrat-social/Du_contrat_social_livre4.mp3", - "image": { - "large": { - "url": "https://upload.wikimedia.org/wikipedia/commons/d/db/Social_contract_rousseau_page.jpg", - "alt": "Du contrat social", - "height": 0, - "width": 0 - }, - "image": "large" - } - } - ], - "startOffset": { - "seconds": "0", - "nanos": 0 - }, - "mediaType": "AUDIO" - }); - - - - - - // - // resp = test.getLatestResponse(); - } - - before('before all', async () => { - // Load project settings to read project ID and trigger phrase. - test = new ActionsOnGoogleTestManager({ projectId: PROJECT_ID }); - await test.writePreviewFromDraft(); - test.setSuiteLocale(DEFAULT_LOCALE); - test.setSuiteSurface(DEFAULT_SURFACE); - }); - - afterEach('post test cleans', async () => { - test.cleanUpAfterTest(); - }); - - it('my list', async () => { - await startConversation(); - await test.sendQuery("quitter"); - // test.assertConversationEnded(); - }); -}); From 869f15b1c2903c392ef21c69205d5eee7fc4099d Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 9 Mar 2022 15:31:06 +0100 Subject: [PATCH 159/180] sdk: bookshelf intent --- sdk/custom/intents/en/bookshelf.yaml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 sdk/custom/intents/en/bookshelf.yaml diff --git a/sdk/custom/intents/en/bookshelf.yaml b/sdk/custom/intents/en/bookshelf.yaml new file mode 100644 index 00000000..e9efd62b --- /dev/null +++ b/sdk/custom/intents/en/bookshelf.yaml @@ -0,0 +1,2 @@ +trainingPhrases: +- bookshelf From 9d9c23583b78bf6b07457a8910e57d788f709f42 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 9 Mar 2022 15:35:44 +0100 Subject: [PATCH 160/180] fix: help intent doesn't say the second sentence --- webhooks/functions/src/controller/handler/home_user.ts | 1 - webhooks/functions/src/translation/en/en.json | 3 +-- webhooks/functions/src/typings/i18n.d.ts | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/webhooks/functions/src/controller/handler/home_user.ts b/webhooks/functions/src/controller/handler/home_user.ts index bb978b69..126c2d6c 100644 --- a/webhooks/functions/src/controller/handler/home_user.ts +++ b/webhooks/functions/src/controller/handler/home_user.ts @@ -86,7 +86,6 @@ const bookshelf: THandlerFn = (m) => { const help: THandlerFn = (m) => { m.say("home_user.help.1", {name: NAME}); - m.say("home_user.help.2", {name: NAME}); m.nextScene = "home_user"; } diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index 2e595073..ac58152c 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -66,8 +66,7 @@ } }, "help": { - "1": "You can search for a specific book by title or author, browse our collections or check your bookshelf to start reading one of your preselected books.", - "2": "What would you like to do?" + "1": "You can search for a specific book by title or author, browse our collections or check your bookshelf to start reading one of your preselected books." } }, "search": { diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index 8b683560..819dc803 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "player.start" | "player.askResumeLastOffset" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", + "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "player.start" | "player.askResumeLastOffset" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" }; keysWithNS: { - "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:search.enter.2" | "en:search.empty.1" | "en:search.empty.2" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:player.start" | "en:player.askResumeLastOffset" | "en:collections.enter.1" | "en:collections.help.1" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", + "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:search.enter.1" | "en:search.enter.2" | "en:search.empty.1" | "en:search.empty.2" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:player.start" | "en:player.askResumeLastOffset" | "en:collections.enter.1" | "en:collections.help.1" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" }; } From 1514c0cf409043f724b3f9c2165372d091f05567 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 23 Mar 2022 11:51:01 +0100 Subject: [PATCH 161/180] squash and merge: cela-dev --- .../workflows/function-deploy-cela-dev.yml | 71 +++++++ .gitignore | 4 + sdk/custom/intents/another_one.yaml | 6 +- sdk/custom/intents/bookshelf.yaml | 11 +- sdk/custom/intents/by_genre.yaml | 5 +- sdk/custom/intents/by_theme.yaml | 5 +- sdk/custom/intents/collections.yaml | 7 +- sdk/custom/intents/en/by_genre.yaml | 2 +- sdk/custom/intents/en/collections.yaml | 1 + sdk/custom/intents/en/learn_more.yaml | 1 + sdk/custom/intents/en/recent_books.yaml | 3 + sdk/custom/intents/en/search.yaml | 2 + sdk/custom/intents/en/selects_book.yaml | 13 +- sdk/custom/intents/help.yaml | 3 +- sdk/custom/intents/learn_more.yaml | 1 + sdk/custom/intents/link_account.yaml | 1 + sdk/custom/intents/maybe_later.yaml | 1 + sdk/custom/intents/recent_books.yaml | 12 ++ sdk/custom/intents/repeat.yaml | 2 + sdk/custom/intents/search.yaml | 16 ++ sdk/custom/intents/search_query.yaml | 3 + sdk/custom/intents/selects_book.yaml | 27 ++- .../scenes/home_new_user_AccountLinking.yaml | 2 +- sdk/custom/scenes/home_user.yaml | 3 + sdk/custom/scenes/info.yaml | 3 + sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 2 + webhooks/.gitignore | 66 ------ webhooks/functions/package-lock.json | 66 +++--- webhooks/functions/package.json | 2 +- webhooks/functions/src/constants.ts | 7 +- .../functions/src/controller/Assistant.ts | 45 ++++- webhooks/functions/src/controller/Machine.ts | 129 ++++++++++-- .../src/controller/handler/home_new_user.ts | 20 +- .../handler/home_new_user_maybe_later.ts | 10 +- .../controller/handler/home_new_user_no.ts | 2 +- .../src/controller/handler/home_user.ts | 72 ++++--- .../functions/src/controller/handler/index.ts | 6 + .../functions/src/controller/handler/info.ts | 10 +- .../functions/src/controller/handler/main.ts | 2 +- .../src/controller/handler/player_prequel.ts | 11 + .../src/controller/handler/search.ts | 4 +- .../src/controller/handler/selection.ts | 10 +- webhooks/functions/src/error.ts | 5 + .../functions/src/sdk/collections.test.ts | 8 +- webhooks/functions/src/sdk/conv.test.ts | 8 +- .../functions/src/sdk/home_new_user.test.ts | 25 +-- .../src/sdk/home_new_user_maybe_later.test.ts | 22 +- .../src/sdk/home_new_user_no.test.ts | 12 +- webhooks/functions/src/sdk/home_user.test.ts | 79 ++++++-- webhooks/functions/src/sdk/info.test.ts | 34 +++- webhooks/functions/src/sdk/main.test.ts | 32 ++- .../functions/src/sdk/player_prequel.test.ts | 5 +- webhooks/functions/src/sdk/search.test.ts | 2 +- webhooks/functions/src/sdk/selection.test.ts | 158 +++++++++++---- webhooks/functions/src/translation/en/en.json | 66 +++--- webhooks/functions/src/translation/fr/fr.json | 189 ++++++++++++------ webhooks/functions/src/typings/i18n.d.ts | 8 +- .../functions/src/typings/sdkHandler.d.ts | 2 +- webhooks/functions/tsconfig.json | 3 +- 59 files changed, 929 insertions(+), 398 deletions(-) create mode 100644 .github/workflows/function-deploy-cela-dev.yml create mode 100644 sdk/custom/intents/en/recent_books.yaml create mode 100644 sdk/custom/intents/recent_books.yaml delete mode 100644 webhooks/.gitignore create mode 100644 webhooks/functions/src/error.ts diff --git a/.github/workflows/function-deploy-cela-dev.yml b/.github/workflows/function-deploy-cela-dev.yml new file mode 100644 index 00000000..220e6332 --- /dev/null +++ b/.github/workflows/function-deploy-cela-dev.yml @@ -0,0 +1,71 @@ + +name: functions deploy + +on: + push: + branches: [ cela-dev ] + paths: + - 'webhooks/**' + - '.github/workflows/function-deploy-cela-dev.yml' + +jobs: + deploy: + name: "Deploy Firebase functions" + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [16.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + env: + working-directory: './webhooks/functions' + project-id: 'cela-2' + defaults: + run: + working-directory: './webhooks/functions' + + steps: + - name: Checkout repo + uses: actions/checkout@v2 + + - name : GITHUB CONTEXT + env: + GITHUB_CONTEXT: ${{ toJson(github) }} + run: echo "$GITHUB_CONTEXT" + + - name: Install node ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + + - name: Install Dependencies + run: npm ci --no-audit + working-directory: ${{ env.working-directory }} + + - name: test + run: npm test + working-directory: ${{ env.working-directory }} + + - name: lint + run: npm run lint + working-directory: ${{ env.working-directory }} + + - name: build + run: npm run build + working-directory: ${{ env.working-directory }} + + - name: set commit name to function config + uses: w9jds/firebase-action@master + with: + args: functions:config:set debug.message=\"${{ github.event.head_commit.message }}\" --project ${{ env.project-id }} + env: + FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} + PROJECT_PATH: './webhooks' + + - name: Deploy to Firebase + uses: w9jds/firebase-action@master + with: + args: deploy --only \"functions:ActionsOnGoogleFulfillment\" --project ${{ env.project-id }} --message \"${{ github.event.head_commit.message }}\" + env: + FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} + PROJECT_PATH: './webhooks' diff --git a/.gitignore b/.gitignore index 7cb323d8..2e88cad1 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,7 @@ node_modules service_account.json + +.nyc_output/ +firebase-debug.log +ui-debug.log diff --git a/sdk/custom/intents/another_one.yaml b/sdk/custom/intents/another_one.yaml index 0967ef42..6ad8421c 100644 --- a/sdk/custom/intents/another_one.yaml +++ b/sdk/custom/intents/another_one.yaml @@ -1 +1,5 @@ -{} +trainingPhrases: +- prochain +- suivant +- page suivante +- un autre diff --git a/sdk/custom/intents/bookshelf.yaml b/sdk/custom/intents/bookshelf.yaml index 0967ef42..6984d2c3 100644 --- a/sdk/custom/intents/bookshelf.yaml +++ b/sdk/custom/intents/bookshelf.yaml @@ -1 +1,10 @@ -{} +trainingPhrases: +- voir mon étagère +- consulter ma liste personnelle +- voir ma liste personnelle +- liste personnelle +- consulter mon étagère +- étagère +- mon étagère +- bibliothèque +- ma bibliothèque diff --git a/sdk/custom/intents/by_genre.yaml b/sdk/custom/intents/by_genre.yaml index 0967ef42..f406e65f 100644 --- a/sdk/custom/intents/by_genre.yaml +++ b/sdk/custom/intents/by_genre.yaml @@ -1 +1,4 @@ -{} +trainingPhrases: +- par genre +- genre +- je préfère par genre diff --git a/sdk/custom/intents/by_theme.yaml b/sdk/custom/intents/by_theme.yaml index 0967ef42..f2725a2c 100644 --- a/sdk/custom/intents/by_theme.yaml +++ b/sdk/custom/intents/by_theme.yaml @@ -1 +1,4 @@ -{} +trainingPhrases: +- par thème +- thème +- je préfère par thème diff --git a/sdk/custom/intents/collections.yaml b/sdk/custom/intents/collections.yaml index 0967ef42..f853d232 100644 --- a/sdk/custom/intents/collections.yaml +++ b/sdk/custom/intents/collections.yaml @@ -1 +1,6 @@ -{} +trainingPhrases: +- recommandations +- collections +- navigue dans les collections +- sélections +- navigue dans les sélections diff --git a/sdk/custom/intents/en/by_genre.yaml b/sdk/custom/intents/en/by_genre.yaml index e1c6f812..1a198d69 100644 --- a/sdk/custom/intents/en/by_genre.yaml +++ b/sdk/custom/intents/en/by_genre.yaml @@ -2,5 +2,5 @@ trainingPhrases: - by genre please - genre - I prefer by genre -- I prefer to get a book selection by genre +- I prefer collections by genre - by genre diff --git a/sdk/custom/intents/en/collections.yaml b/sdk/custom/intents/en/collections.yaml index 8ab286a5..f6a9901a 100644 --- a/sdk/custom/intents/en/collections.yaml +++ b/sdk/custom/intents/en/collections.yaml @@ -1,3 +1,4 @@ trainingPhrases: +- recommendations - collections - Browse collections diff --git a/sdk/custom/intents/en/learn_more.yaml b/sdk/custom/intents/en/learn_more.yaml index a98a3043..105f4309 100644 --- a/sdk/custom/intents/en/learn_more.yaml +++ b/sdk/custom/intents/en/learn_more.yaml @@ -1,2 +1,3 @@ trainingPhrases: +- information - learn more diff --git a/sdk/custom/intents/en/recent_books.yaml b/sdk/custom/intents/en/recent_books.yaml new file mode 100644 index 00000000..23703a23 --- /dev/null +++ b/sdk/custom/intents/en/recent_books.yaml @@ -0,0 +1,3 @@ +trainingPhrases: +- resume playings +- recent books diff --git a/sdk/custom/intents/en/search.yaml b/sdk/custom/intents/en/search.yaml index 18bdbbcf..41504ffa 100644 --- a/sdk/custom/intents/en/search.yaml +++ b/sdk/custom/intents/en/search.yaml @@ -1,4 +1,6 @@ trainingPhrases: +- find +- search for - I am looking for a book ($query 'The Little Prince by Antoine de Saint-Exupéry' auto=false) - I want to listen ($query 'this book title' auto=false) diff --git a/sdk/custom/intents/en/selects_book.yaml b/sdk/custom/intents/en/selects_book.yaml index bc26304d..5656aaba 100644 --- a/sdk/custom/intents/en/selects_book.yaml +++ b/sdk/custom/intents/en/selects_book.yaml @@ -1,11 +1,16 @@ trainingPhrases: +- ($number 'four' auto=true) +- ($number 'five' auto=true) +- number ($number 'five' auto=true) +- number ($number 'four' auto=true) +- number ($number 'three' auto=true) +- the ($number 'fifth' auto=false) +- the ($number 'fourth' auto=false) - the ($number 'first' auto=false) - the ($number 'second' auto=false) - the ($number 'third' auto=false) -- the number ($number 'one' auto=false) -- the number ($number 'three' auto=true) - ($number 'three' auto=true) - ($number 'two' auto=true) - ($number 'one' auto=false) -- the ($number 'two' auto=true) -- the ($number 'one' auto=false) +- number ($number 'two' auto=false) +- number ($number 'one' auto=false) diff --git a/sdk/custom/intents/help.yaml b/sdk/custom/intents/help.yaml index 3693bbe9..61394d5c 100644 --- a/sdk/custom/intents/help.yaml +++ b/sdk/custom/intents/help.yaml @@ -1,3 +1,4 @@ trainingPhrases: - aide -- aider moi +- aide moi +- de l'aide diff --git a/sdk/custom/intents/learn_more.yaml b/sdk/custom/intents/learn_more.yaml index 429fd2cb..e193efdc 100644 --- a/sdk/custom/intents/learn_more.yaml +++ b/sdk/custom/intents/learn_more.yaml @@ -1,3 +1,4 @@ trainingPhrases: +- en apprendre plus - en savoir plus - information diff --git a/sdk/custom/intents/link_account.yaml b/sdk/custom/intents/link_account.yaml index e21fe370..1de587a0 100644 --- a/sdk/custom/intents/link_account.yaml +++ b/sdk/custom/intents/link_account.yaml @@ -1,2 +1,3 @@ trainingPhrases: - je veux me connecter +- me connecter diff --git a/sdk/custom/intents/maybe_later.yaml b/sdk/custom/intents/maybe_later.yaml index cec179b0..59497421 100644 --- a/sdk/custom/intents/maybe_later.yaml +++ b/sdk/custom/intents/maybe_later.yaml @@ -1,2 +1,3 @@ trainingPhrases: - plus tard +- peut être plus tard diff --git a/sdk/custom/intents/recent_books.yaml b/sdk/custom/intents/recent_books.yaml new file mode 100644 index 00000000..2bf7418c --- /dev/null +++ b/sdk/custom/intents/recent_books.yaml @@ -0,0 +1,12 @@ +trainingPhrases: +- mes livres récents +- reprends +- reprendre ma lecture +- reprendre la lecture +- derniers livres +- livres récents +- voir mes derniers livres +- voir mes livres récents +- reprendre ma lecture +- reprendre la lecture +- derniers livres lus diff --git a/sdk/custom/intents/repeat.yaml b/sdk/custom/intents/repeat.yaml index bc2af48e..4fbe20bb 100644 --- a/sdk/custom/intents/repeat.yaml +++ b/sdk/custom/intents/repeat.yaml @@ -1,2 +1,4 @@ trainingPhrases: - répéter +- répête +- je ne comprends pas diff --git a/sdk/custom/intents/search.yaml b/sdk/custom/intents/search.yaml index 4453fe05..8b338ae1 100644 --- a/sdk/custom/intents/search.yaml +++ b/sdk/custom/intents/search.yaml @@ -2,3 +2,19 @@ parameters: - name: query type: name: string +trainingPhrases: +- chercher un livre +- chercher un livre audio +- chercher ($number1 'un' auto=true) nouveau livre +- chercher +- je veux chercher un livre audio +- je veux chercher un livre +- recherche un livre +- recherche +- je veux rechercher un livre +- Je recherche ($query 'Le Petit Prince par Antoine de Saint-Exupéry' auto=false) +- Cherche ($query 'La Peste' auto=false) +- Recherche ($query 'La Horla' auto=false) +- Je veux écouter ($query 'Ce livre' auto=false) +- Je veux lire ($query 'Ce livre par cet auteur' auto=false) +- Je cherche un livre écrit par ($query 'Auteur' auto=false) diff --git a/sdk/custom/intents/search_query.yaml b/sdk/custom/intents/search_query.yaml index 4453fe05..13277820 100644 --- a/sdk/custom/intents/search_query.yaml +++ b/sdk/custom/intents/search_query.yaml @@ -2,3 +2,6 @@ parameters: - name: query type: name: string +trainingPhrases: +- ($query 'La Peste de Camus' auto=false) +- ($query 'Le Petit Prince par Antoine de Saint-Exupéry' auto=false) diff --git a/sdk/custom/intents/selects_book.yaml b/sdk/custom/intents/selects_book.yaml index 59df0111..2bde62a1 100644 --- a/sdk/custom/intents/selects_book.yaml +++ b/sdk/custom/intents/selects_book.yaml @@ -3,10 +3,23 @@ parameters: type: name: actions.type.Number trainingPhrases: -- ($letter 'c' auto=false) -- ($letter 'b' auto=false) -- ($letter 'C' auto=false) -- ($letter 'B' auto=false) -- ($letter 'ah' auto=false) -- ($letter 'A' auto=false) -- ($letter 'a' auto=false) +- Le ($number 'premier' auto=false) +- Le ($number 'second' auto=false) +- Le ($number 'troisième' auto=false) +- Le ($number 'quatrième' auto=false) +- Le ($number 'cinquième' auto=false) +- Numéro ($number 'un' auto=false) +- Numéro ($number 'deux' auto=false) +- Numéro ($number 'trois' auto=false) +- Numéro ($number 'quatre' auto=false) +- Numéro ($number 'cinq' auto=false) +- Le numéro ($number 'un' auto=false) +- Le numéro ($number 'deux' auto=false) +- Le numéro ($number 'trois' auto=false) +- Le numéro ($number 'quatre' auto=false) +- Le numéro ($number 'cinq' auto=false) +- ($number 'un' auto=false) +- ($number 'deux' auto=false) +- ($number 'trois' auto=false) +- ($number 'quatre' auto=false) +- ($number 'cinq' auto=false) diff --git a/sdk/custom/scenes/home_new_user_AccountLinking.yaml b/sdk/custom/scenes/home_new_user_AccountLinking.yaml index 88d96d7b..38550691 100644 --- a/sdk/custom/scenes/home_new_user_AccountLinking.yaml +++ b/sdk/custom/scenes/home_new_user_AccountLinking.yaml @@ -11,7 +11,7 @@ slots: writeSessionParam: AccountLinkingSlot config: '@type': type.googleapis.com/google.actions.conversation.v3.SignInSpec - opt_context: To keep using EDRLab + opt_context: "" defaultValue: sessionParam: AccountLinkingSlot name: AccountLinkingSlot diff --git a/sdk/custom/scenes/home_user.yaml b/sdk/custom/scenes/home_user.yaml index 88cd0ef2..4395e757 100644 --- a/sdk/custom/scenes/home_user.yaml +++ b/sdk/custom/scenes/home_user.yaml @@ -14,6 +14,9 @@ intentEvents: - handler: webhookHandler: home_user__intent__search intent: search +- handler: + webhookHandler: home_user__intent__recent_books + intent: recent_books - handler: webhookHandler: home_user__intent__fallback intent: actions.intent.NO_MATCH_1 diff --git a/sdk/custom/scenes/info.yaml b/sdk/custom/scenes/info.yaml index 88d61bd0..f1538109 100644 --- a/sdk/custom/scenes/info.yaml +++ b/sdk/custom/scenes/info.yaml @@ -13,6 +13,9 @@ intentEvents: webhookHandler: info__intent__yes intent: membership transitionToScene: actions.scene.END_CONVERSATION +- handler: + webhookHandler: info__intent__no + intent: "no" - handler: webhookHandler: info__intent__fallback intent: actions.intent.NO_MATCH_1 diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index 7fce1ff0..85df2d22 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -83,6 +83,8 @@ handlers: - name: player_prequel__on_enter - name: player_prequel__intent__yes - name: player_prequel__intent__no +- name: home_user__intent__recent_books +- name: info__intent__no httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/.gitignore b/webhooks/.gitignore deleted file mode 100644 index dbb58ffb..00000000 --- a/webhooks/.gitignore +++ /dev/null @@ -1,66 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -firebase-debug.log* -firebase-debug.*.log* - -# Firebase cache -.firebase/ - -# Firebase config - -# Uncomment this if you'd like others to create their own Firebase project. -# For a team working on the same Firebase project(s), it is recommended to leave -# it commented so all members can deploy to the same project(s) in .firebaserc. -# .firebaserc - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env diff --git a/webhooks/functions/package-lock.json b/webhooks/functions/package-lock.json index cad82d1e..75d3aa25 100644 --- a/webhooks/functions/package-lock.json +++ b/webhooks/functions/package-lock.json @@ -1163,9 +1163,9 @@ "dev": true }, "@xmldom/xmldom": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.0.tgz", - "integrity": "sha512-7wVnF+rKrVDEo1xjzkkidTG0grclaVnX0vKa0z9JSXcEdtftUJjvU33jLGg6SHyvs3eeqEsI7jZ6NxYfRypEEg==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.1.tgz", + "integrity": "sha512-4wOae+5N2RZ+CZXd9ZKwkaDi55IxrSTOjHpxTvQQ4fomtOJmqVxbmICA9jE1jvnqNhpfgz8cnfFagG86wV/xLQ==" }, "abort-controller": { "version": "3.0.0", @@ -2356,9 +2356,9 @@ } }, "fetch-cookie": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-1.0.0.tgz", - "integrity": "sha512-SWcAhkDe4yVBFtwRqJNmot6k1XjjzI7tw3aRHepxXrK6FQp6obBhqcnsdm2aNUzrtE71607crNAYodtKMq3TjA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-1.0.1.tgz", + "integrity": "sha512-gfQjp/UOsjHeuFzkOqjcYtJ20qhRzyhdK5fV2i7Qh+8bT0+HH2TKPl1ql+u39gsTcmehFX9vhvULZAsXACApgQ==", "requires": { "tough-cookie": "^2.3.3 || ^3.0.1 || ^4.0.0" } @@ -2889,8 +2889,7 @@ "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, "html-escaper": { "version": "2.0.2", @@ -3787,9 +3786,9 @@ } }, "nanoid": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", - "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==" + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==" }, "natural-compare": { "version": "1.4.0", @@ -4079,15 +4078,15 @@ } }, "opds-fetcher-parser": { - "version": "git+https://github.com/edrlab/opds_fetcher_parser.git#03a9eb705e05f4ebf02ea2815c47707aec8705c7", - "from": "git+https://github.com/edrlab/opds_fetcher_parser.git#03a9eb705e05f4ebf02ea2815c47707aec8705c7", + "version": "git+https://github.com/edrlab/opds_fetcher_parser.git#f74c1bfbaccc7508de2445bb16aacc8bd6ad9641", + "from": "git+https://github.com/edrlab/opds_fetcher_parser.git#f74c1bfbaccc7508de2445bb16aacc8bd6ad9641", "requires": { "moment": "^2.29.1", "nanoid": "^3.1.23", "r2-lcp-js": "^1.0.30", "r2-opds-js": "^1.0.35", "r2-shared-js": "^1.0.51", - "ts-fetch": "github:edrlab/ts_fetch#a55cdd950c57e060f9950808af5ddc5d87754263" + "ts-fetch": "github:edrlab/ts_fetch#bc8166db8813b791a212f521ef79a74f0ea5b175" } }, "optionator": { @@ -4469,18 +4468,19 @@ } }, "r2-shared-js": { - "version": "1.0.55", - "resolved": "https://registry.npmjs.org/r2-shared-js/-/r2-shared-js-1.0.55.tgz", - "integrity": "sha512-kON3ZOXThEkbxJS0yZ8OD604kzEDq87rB8akdB6l5QR9LCs38nvRDxkEtnt0ZVVYmQnd80GXg2yH5c/OR4YBEw==", + "version": "1.0.56", + "resolved": "https://registry.npmjs.org/r2-shared-js/-/r2-shared-js-1.0.56.tgz", + "integrity": "sha512-HLhrCjn7/nL44mqf6rtSiguddXBMiXpr02z14wlNy28EMyxFG8ir7iZYYwVmZ6h+BOVgTYvml+4u8rqHsJNRrg==", "requires": { - "@xmldom/xmldom": "^0.8.0", + "@xmldom/xmldom": "^0.8.1", "debug": "^4.3.3", "fast-deep-equal": "^3.1.3", - "image-size": "^1.0.0", + "he": "^1.2.0", + "image-size": "^1.0.1", "mime-types": "^2.1.34", "moment": "^2.29.1", - "r2-lcp-js": "^1.0.34", - "r2-utils-js": "^1.0.30", + "r2-lcp-js": "^1.0.35", + "r2-utils-js": "^1.0.31", "slugify": "^1.6.5", "ta-json-x": "^2.5.3", "tslib": "^2.3.1", @@ -4497,16 +4497,16 @@ } }, "mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "requires": { - "mime-db": "1.51.0" + "mime-db": "1.52.0" } } } @@ -5105,8 +5105,8 @@ "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=" }, "ts-fetch": { - "version": "github:edrlab/ts_fetch#a55cdd950c57e060f9950808af5ddc5d87754263", - "from": "github:edrlab/ts_fetch#a55cdd950c57e060f9950808af5ddc5d87754263", + "version": "github:edrlab/ts_fetch#bc8166db8813b791a212f521ef79a74f0ea5b175", + "from": "github:edrlab/ts_fetch#bc8166db8813b791a212f521ef79a74f0ea5b175", "requires": { "fetch-cookie": "^1.0.0", "node-fetch": "^2.6.7", @@ -5508,9 +5508,9 @@ } }, "urijs": { - "version": "1.19.7", - "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.7.tgz", - "integrity": "sha512-Id+IKjdU0Hx+7Zx717jwLPsPeUqz7rAtuVBRLLs+qn+J2nf9NGITWVCxcijgYxBqe83C7sqsQPs6H1pyz3x9gA==" + "version": "1.19.10", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.10.tgz", + "integrity": "sha512-EzauQlgKuJgsXOqoMrCiePBf4At5jVqRhXykF3Wfb8ZsOBMxPcfiVBcsHXug4Aepb/ICm2PIgqAUGMelgdrWEg==" }, "util-deprecate": { "version": "1.0.2", diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index c3f823ca..8568d1db 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -28,7 +28,7 @@ "firebase-admin": "^9.8.0", "firebase-functions": "^3.16.0", "i18next": "^21.5.3", - "opds-fetcher-parser": "git+https://github.com/edrlab/opds_fetcher_parser.git#03a9eb705e05f4ebf02ea2815c47707aec8705c7", + "opds-fetcher-parser": "git+https://github.com/edrlab/opds_fetcher_parser.git#f74c1bfbaccc7508de2445bb16aacc8bd6ad9641", "reflect-metadata": "^0.1.13", "validator": "^13.7.0" }, diff --git a/webhooks/functions/src/constants.ts b/webhooks/functions/src/constants.ts index 2d1f95a5..8e5d297e 100644 --- a/webhooks/functions/src/constants.ts +++ b/webhooks/functions/src/constants.ts @@ -1,7 +1,9 @@ - export const NAME = "EDRLAB"; +export const setName = (locale: TLang) => {}; + export const API_BASE_URL = "https://storage.googleapis.com/audiobook_edrlab/feed.json"; +export const EDRLAB_FUNCTION_URL = 'https://us-central1-edrlab-1.cloudfunctions.net/manifest'; export const ALL_PUBLICATION_LIST_URL = "https://storage.googleapis.com/audiobook_edrlab/navigation/all.json"; export const BOOKSHELF_URL = 'https://storage.googleapis.com/audiobook_edrlab/groups/popular.json'; @@ -19,5 +21,6 @@ export const LAST_SEEN_THRESHOLD = 72; export const PROJECT_ID = 'edrlab-1'; +export const TIMER = 8000; -type TLang = 'fr' | 'en'; +export type TLang = 'fr' | 'en'; diff --git a/webhooks/functions/src/controller/Assistant.ts b/webhooks/functions/src/controller/Assistant.ts index edb84dee..8b2b5d7f 100644 --- a/webhooks/functions/src/controller/Assistant.ts +++ b/webhooks/functions/src/controller/Assistant.ts @@ -1,17 +1,20 @@ import {BaseApp, conversation, ConversationV3, ConversationV3App, OmniHandler} from '@assistant/conversation'; import {OpdsFetcher} from 'opds-fetcher-parser'; -import {PROJECT_ID} from '../constants'; +import {DEFAULT_LANGUAGE, PROJECT_ID, setName, TIMER, TLang} from '../constants'; import {StorageModel} from '../model/storage.model'; import {THandlerFn} from '../type'; import {TSdkHandler} from '../typings/sdkHandler'; import {TSdkScene} from '../typings/sdkScene'; import {enter as selectionEnter} from './handler/selection'; import {Machine} from './Machine'; +import {ok} from 'assert'; +import {WebpubError} from '../error'; export class Assistant { private _app: OmniHandler & BaseApp & ConversationV3App; private _storageModel: StorageModel | undefined; private _fetcher: OpdsFetcher | undefined; + private _locale: TLang; constructor({ storageModel, @@ -25,6 +28,8 @@ export class Assistant { debug: process.env['NODE_ENV'] === 'development' ? true : false, }); + this._locale = DEFAULT_LANGUAGE; + this._app.catch((conv, error) => { console.error('APP CATCH ERROR', error); @@ -32,12 +37,22 @@ export class Assistant { conv.scene.next.name = 'actions.scene.END_CONVERSATION'; } - // @TODO fix translation - conv.add('Oops, something went wrong. I will exit the app. Feel free to reopen it as soon as possible.'); - - // @TODO - // remove session - // and return to main menu or home_user if authenticated + // error instanceOf WebpubError !== True ?! why? + if ((error as WebpubError).code === 401) { + console.log('WEBPUB ERROR code 401'); + + if (this._locale === 'en') { + conv.add('Sorry, it is not possible to go further. Please unlink your CELA account from your assistant, then link them again.'); + } else if (this._locale === 'fr') { + conv.add('Désolé, impossible d\'aller plus loin : dissociez votre compte CAÉB de votre assistant puis ré-associez les.'); + } + } else { + if (this._locale === 'en') { + conv.add('Oops, something went wrong. I will exit the app. Feel free to reopen it as soon as possible.'); + } else if (this._locale === 'fr') { + conv.add('Oups, quelque chose s\'est mal passé.'); + } + } }); if (storageModel) { @@ -53,8 +68,18 @@ export class Assistant { public handle = (path: TSdkHandler, fn: THandlerFn) => { this._app.handle(path, async (conv) => { + // @TODO need to send an alert to google log on timeout error + const timerP = new Promise((_, rej) => setTimeout(() => rej(new Error('TIMEOUT')), TIMER)); const machine = new Machine(conv); + const locale = (conv.user.locale || '').split('-')[0]; + console.log('LOCALE=', locale); + ok(locale === 'fr' || locale === 'en', 'locale not known ' + locale); + setName(locale); + this._locale = locale; + + await machine.setLanguage(locale); + console.info('ASSISTANT:', path); console.info('scene.name=', conv.scene.name); console.info('linkingStatus', conv.user.accountLinkingStatus); @@ -62,13 +87,13 @@ export class Assistant { const bearerToken = conv.user.params.bearerToken; await machine.begin({bearerToken, storageModel: this._storageModel, fetcher: this._fetcher}); - await Promise.resolve(fn(machine)); + await Promise.race([timerP, Promise.resolve(fn(machine))]); // HACK // google actions platform doesn't allow to set the same next scene name than the actual in the 'on_enter' handler scene // it's a platform limitation for a basic infinite loop I think - if (path === 'selection__intent__selects_book' && conv.scene.next?.name as TSdkScene === 'selection') { - await Promise.resolve(selectionEnter(machine)); + if (path === 'selection__intent__selects_book' && conv.scene.next?.name as TSdkScene === 'selection' && machine.getSessionState('selection') === 'FINISH') { + await Promise.race([timerP, Promise.resolve(selectionEnter(machine))]); } await machine.end(); diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index cc929d03..2eaf0bb5 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -1,6 +1,6 @@ import {ok} from 'assert'; import {AuthenticationStorage, http as httpOpdsFetcherParser, OpdsFetcher} from 'opds-fetcher-parser'; -import {API_BASE_URL, LAST_SEEN_THRESHOLD, PADDING_GROUP, PADDING_PUB} from '../constants'; +import {API_BASE_URL, DEFAULT_LANGUAGE, EDRLAB_FUNCTION_URL, LAST_SEEN_THRESHOLD, PADDING_GROUP, PADDING_PUB, TLang} from '../constants'; import {ISessionScene, TKeySessionScene, TKindSelection, TStateAuthentication} from '../model/storage.interface'; import {StorageModel} from '../model/storage.model'; import {i18n, TI18n, TI18nKey} from '../translation'; @@ -9,14 +9,16 @@ import {resetSelection} from './handler/selection.helper'; import validator from 'validator'; import {Media} from '@assistant/conversation'; import {MediaType, OptionalMediaControl} from '@assistant/conversation/dist/api/schema'; -import {IOpdsLinkView} from 'opds-fetcher-parser/build/src/interface/opds'; +import {IOpdsLinkView, IOpdsPublicationView, IOpdsResultView} from 'opds-fetcher-parser/build/src/interface/opds'; import {TSdkHandler} from '../typings/sdkHandler'; +import {WebpubError} from '../error'; export class Machine { private _conv: IConversationV3; private _i18n: TI18n; private _model: StorageModel | undefined; private _fetcher: OpdsFetcher | undefined; + private _locale: TLang; private _sayAcc: string; @@ -29,6 +31,7 @@ export class Machine { this._conv = conv; this._sayAcc = ''; + this._locale = DEFAULT_LANGUAGE; } public async begin({ @@ -47,6 +50,8 @@ export class Machine { } else { if (typeof bearerToken === 'string') { this._model = await StorageModel.create(bearerToken); + } else { + console.info('No Bearer Token Available'); } } @@ -59,7 +64,11 @@ export class Machine { accessToken: bearerToken, authenticationUrl: API_BASE_URL, }); - const http = new httpOpdsFetcherParser(undefined, authenticationStorage); + authenticationStorage.setAuthenticationToken({ + accessToken: bearerToken, + authenticationUrl: EDRLAB_FUNCTION_URL, + }); + const http = new httpOpdsFetcherParser(undefined, authenticationStorage, this._locale); this._fetcher = new OpdsFetcher(http); } } @@ -93,6 +102,11 @@ export class Machine { return this._conv.user.accountLinkingStatus; } + public setLanguage(locale: TLang) { + this._locale = locale; + return this._i18n.changeLanguage(locale); + } + public set nextScene(scene: TSdkScene2) { const obj = this._conv.scene; @@ -148,6 +162,14 @@ export class Machine { return this._model.store.player.history.size; } + public get playingHistorySortByDate() { + ok(this._model); + return new Map( + [...this._model.store.player.history] + .sort(([, {date: dateA}], [, {date: dateB}]) => dateB.getTime() - dateA.getTime()), + ); + } + public async getCurrentPlayingTitleAndChapter() { ok(this._model); @@ -196,13 +218,10 @@ export class Machine { if (!this.isValidHttpUrl(url)) { throw new Error('not valid playing url'); } - if (!time || !index) { + if (time === 0 && index === 0) { return false; } - if (time > 0 || index > 0) { - return true; - } - return false; + return true; } public get playerCurrent() { @@ -217,7 +236,8 @@ export class Machine { from: TSdkHandler, url: string, }) { - if (!this.isValidHttpUrl(url)) { + // @ts-ignore + if (!this.isValidHttpUrl(url) && !url.startsWith('data://')) { // data:// for recent books throw new Error('not a valid url'); } this.selectionSession = { @@ -253,11 +273,35 @@ export class Machine { public async selectPublication(url: string, number: number) { ok(this._model); - if (!this.isValidHttpUrl(url)) { + // @ts-ignore + if (!this.isValidHttpUrl(url) && !url.startsWith('data://')) { // recent books throw new Error('url not valid'); } - const pub = await this.getPublicationFromNumberInSelectionWithUrl(url, number); + let pub: { + title: string; + author: string; + webpubUrl: string; + } | undefined; + + if (url.startsWith('data://')) { + const dataStr = url.substring('data://'.length); + const data = JSON.parse(dataStr); + ok(Array.isArray(data)); + + const urlFromData = data[number - 1]; + if (this.isValidHttpUrl(urlFromData)) { + const webpub = await this.webpubRequest(urlFromData); + pub = { + title: webpub.title, + author: webpub.authors[0] || '', + webpubUrl: urlFromData, + }; + } + } else { + pub = await this.getPublicationFromNumberInSelectionWithUrl(url, number); + } + if (pub) { const webpubUrl = pub.webpubUrl; if (!this.isValidHttpUrl(webpubUrl)) { @@ -471,10 +515,6 @@ export class Machine { const startTimeRaw = this._model.store.player.current.time; const webpub = await this.webpubRequest(url); - if (!webpub) { - throw new Error('no webpub'); - // @TODO how to handle these errors : just tell it to the user that the webpub is not readable and must choice an another - } let startIndex = (startIndexRaw && startIndexRaw > -1 && startIndexRaw <= webpub.readingOrders.length) ? startIndexRaw : @@ -523,18 +563,64 @@ export class Machine { if (!this._fetcher) { throw new Error('no fetcher available !'); } - const webpub = await this._fetcher.webpubRequest(url); - return webpub; + try { + const webpub = await this._fetcher.webpubRequest(url); + return webpub; + } catch (e) { + const error = new WebpubError(`${e?.toString ? e.toString() : e}`); + error.code = 401; + throw error; + } } private async feedRequest(url: string) { + if (!this._fetcher) { + throw new Error('no fetcher available !'); + } + + // recent books hack + if (url.startsWith('data://')) { + const dataStr = url.substring('data://'.length); + const data = JSON.parse(dataStr); + ok(Array.isArray(data)); + + const publications: IOpdsPublicationView[] = []; + for (const urlFromData of data) { + const webpub = await this._fetcher.webpubRequest(urlFromData); + const title = webpub.title || ''; + const authors = webpub.authors || []; + publications.push({ + title, + // @ts-ignore + authors: [{name: authors[0]}], + openAccessLinks: [{ + url: urlFromData, + }], + }); + } + + const feed: IOpdsResultView = { + title: 'recent books', + publications, + }; + + return feed; + } + if (!validator.isURL(url)) { throw new Error('url not valid : ' + url); } - if (!this._fetcher) { - throw new Error('no fetcher available !'); + let feed: IOpdsResultView = { + title: '', + publications: [], + }; + try { + feed = await this._fetcher.feedRequest(url); + } catch (e) { + console.error('FETCHER ERROR START'); + console.error(e); + console.error('FETCHER ERROR END'); } - const feed = await this._fetcher.feedRequest(url); return feed; } @@ -553,7 +639,8 @@ export class Machine { const sameSession = id === idFromStore; if (sameSession) { console.info('MIDDLEWARE :: Session in progress'); - this.setSessionState('home_user', 'SESSION'); + // see home_user.ts + // this.setSessionState('home_user', 'SESSION'); } else { console.info('MIDDLEWARE :: new SESSION'); this._model.store.session = { diff --git a/webhooks/functions/src/controller/handler/home_new_user.ts b/webhooks/functions/src/controller/handler/home_new_user.ts index b4dd6b5b..3a82e3ea 100644 --- a/webhooks/functions/src/controller/handler/home_new_user.ts +++ b/webhooks/functions/src/controller/handler/home_new_user.ts @@ -19,22 +19,26 @@ export const home_new_user = (app: Assistant) => { } const enter: THandlerFn = (m) => { - m.say("home_new_user.enter.first.1", { name: NAME }); - m.say("home_new_user.enter.first.2", { name: NAME }); -} -const help: THandlerFn = (m) => { + // m.say("home_new_user.enter.first.1", { name: NAME }); + // m.say("home_new_user.enter.first.2", { name: NAME }); m.say("home_new_user.help.1", {name: NAME}); m.say("home_new_user.help.2", {name: NAME}); +} + +const help: THandlerFn = (m) => { + + // m.say("home_new_user.help.1", {name: NAME}); + // m.say("home_new_user.help.2", {name: NAME}); m.nextScene = "home_new_user"; } const maybeLater: THandlerFn = (m) => { - m.say("home_new_user.maybeLater.1", {name: NAME}); - m.say("home_new_user.maybeLater.2") + // m.say("home_new_user.maybeLater.1", {name: NAME}); + // m.say("home_new_user.maybeLater.2") m.nextScene = "home_new_user_maybe_later"; } @@ -47,8 +51,8 @@ const yes: THandlerFn = (m) => { const no: THandlerFn = (m) => { - m.say("home_new_user.no.1", {name: NAME}); - m.say("home_new_user.no.2", {name: NAME}); + // m.say("home_new_user.no.1", {name: NAME}); + // m.say("home_new_user.no.2", {name: NAME}); m.nextScene = "home_new_user_no"; } diff --git a/webhooks/functions/src/controller/handler/home_new_user_maybe_later.ts b/webhooks/functions/src/controller/handler/home_new_user_maybe_later.ts index 1b845186..bbe07ff2 100644 --- a/webhooks/functions/src/controller/handler/home_new_user_maybe_later.ts +++ b/webhooks/functions/src/controller/handler/home_new_user_maybe_later.ts @@ -18,8 +18,10 @@ export const home_new_user_maybe_later = (app: Assistant) => { } const enter: THandlerFn = (m) => { - m.say("home_new_user.maybeLater.1", { name: NAME }); - m.say("home_new_user.maybeLater.2", { name: NAME }); + // m.say("home_new_user.maybeLater.1", { name: NAME }); + // m.say("home_new_user.maybeLater.2", { name: NAME }); + + m.say("home_new_user_maybe_later.help.1", {name: NAME}); } const linkAccount: THandlerFn = (m) => { @@ -29,7 +31,7 @@ const linkAccount: THandlerFn = (m) => { const help: THandlerFn = (m) => { - m.say("home_new_user_maybe_later.help.1", {name: NAME}); + // m.say("home_new_user_maybe_later.help.1", {name: NAME}); m.nextScene = "home_new_user_maybe_later"; } @@ -41,7 +43,7 @@ const repeat: THandlerFn = (m) => { const learnMore: THandlerFn = (m) => { - m.say("info.about.1", { name: NAME }); + // m.say("info.about.1", { name: NAME }); m.nextScene = "info"; } \ No newline at end of file diff --git a/webhooks/functions/src/controller/handler/home_new_user_no.ts b/webhooks/functions/src/controller/handler/home_new_user_no.ts index 02320075..c7809ee6 100644 --- a/webhooks/functions/src/controller/handler/home_new_user_no.ts +++ b/webhooks/functions/src/controller/handler/home_new_user_no.ts @@ -31,7 +31,7 @@ const help: THandlerFn = (m) => { const yes: THandlerFn = (m) => { - m.say("info.about.1", {name: NAME}); + // m.say("info.about.1", {name: NAME}); m.nextScene = "info"; } diff --git a/webhooks/functions/src/controller/handler/home_user.ts b/webhooks/functions/src/controller/handler/home_user.ts index 126c2d6c..200959af 100644 --- a/webhooks/functions/src/controller/handler/home_user.ts +++ b/webhooks/functions/src/controller/handler/home_user.ts @@ -1,4 +1,4 @@ -import { BOOKSHELF_URL, GENRE_LIST_URL, NAME } from "../../constants"; +import { BOOKSHELF_URL, GENRE_LIST_URL, NAME, PADDING_PUB } from "../../constants"; import { THandlerFn } from "../../type"; import { Assistant } from "../Assistant"; import { missing } from "./void"; @@ -15,52 +15,67 @@ export const home_user = (app: Assistant) => { app.handle("home_user__intent__repeat", repeat); app.handle("home_user__intent__silence", help); app.handle("home_user__intent__silence_end", missing); + app.handle("home_user__intent__recent_books", recentBooks); } const enter: THandlerFn = async (m) => { const state = m.getSessionState("home_user"); + const newlyLinked = m.authenticationState === "NEWLY_LINKED"; + const playing = m.playingInProgress; + const regularUser = m.isARegularUser; + if (state === "SESSION") { // aka there is a session : the user discovered the app - m.say("home_user.enter.regular.1"); - return; - } + // "What would you like to do?" + // m.say("home_user.enter.regular.1"); + + // "Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?" + m.say("home_user.enter.newlyUser.2"); + + } else if (state === "REPEAT") { + + m.say("home_user.help.1"); + m.say("home_user.help.2"); + + m.setSessionState("home_user", "SESSION"); + + } else if (newlyLinked) { - const newlyLinked = m.authenticationState === "NEWLY_LINKED"; - if (newlyLinked) { m.say("home_user.enter.newlyUser.1", { name: NAME }); m.say("home_user.enter.newlyUser.2", { name: NAME }); - return; - } - const playing = m.playingInProgress; - if (playing) { + } else if (playing) { const {title, chapter, author} = await m.getCurrentPlayingTitleAndChapter(); - const readingNumber = m.playingNumber; + const readingNumber = m.playingNumber - 1; m.say("home_user.enter.playing.1", {chapterNumber: chapter, titleAndAuthor: `${title}${author ? `, ${author}` : ''}`}); - if (readingNumber) { + if (readingNumber > 0) { m.say("home_user.enter.playing.2", {readingNumber: readingNumber}); } m.say("home_user.enter.playing.3"); m.say("home_user.enter.regular.1"); + m.say("home_user.enter.regular.2"); - return ; - } - - const regularUser = m.isARegularUser; - if (regularUser) { + } else if (regularUser) { // regularUser - // what is the purpose of this information ? - // @TODO ask to Maiike + + m.say("home_user.enter.regular.1"); + m.say("home_user.enter.regular.2"); } else { // occasionalUser + + // "Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?" + m.say("home_user.enter.newlyUser.2"); } - - m.say("home_user.enter.newlyUser.2"); + + m.setSessionState("home_user", "SESSION"); + + // "Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?" + // m.say("home_user.enter.newlyUser.2"); } const search: THandlerFn = (m) => { @@ -83,9 +98,20 @@ const bookshelf: THandlerFn = (m) => { }); } +const recentBooks: THandlerFn = (m) => { + + const history = m.playingHistorySortByDate; + const urls = [...history.keys()]; + m.initAndGoToSelectionSession({ + kind: 'PUBLICATION', + from: "home_user__intent__recent_books", + url: 'data://' + JSON.stringify(urls.slice(0, PADDING_PUB)), // data url with an array of webpub links + }) +} + const help: THandlerFn = (m) => { - m.say("home_user.help.1", {name: NAME}); + m.setSessionState("home_user", "REPEAT"); m.nextScene = "home_user"; } @@ -94,4 +120,4 @@ const repeat: THandlerFn = (m) => { m.setSessionState("home_user", "REPEAT"); m.nextScene = "home_user"; -} \ No newline at end of file +} diff --git a/webhooks/functions/src/controller/handler/index.ts b/webhooks/functions/src/controller/handler/index.ts index 682a7c5c..b34ec572 100644 --- a/webhooks/functions/src/controller/handler/index.ts +++ b/webhooks/functions/src/controller/handler/index.ts @@ -16,6 +16,8 @@ export const handler = (app = new Assistant({})) => { app.handle('main', main); app.handle('cancel', (m) => { + + m.persistMediaPlayer(); m.say('bye.1'); }); @@ -28,6 +30,8 @@ export const handler = (app = new Assistant({})) => { }); app.handle('fallback_end', (m) => { + + m.persistMediaPlayer(); m.say('bye.1'); }); @@ -40,6 +44,8 @@ export const handler = (app = new Assistant({})) => { }); app.handle('silence_end', (m) => { + + m.persistMediaPlayer(); m.say('bye.1'); }); diff --git a/webhooks/functions/src/controller/handler/info.ts b/webhooks/functions/src/controller/handler/info.ts index bd1b4e8a..da547507 100644 --- a/webhooks/functions/src/controller/handler/info.ts +++ b/webhooks/functions/src/controller/handler/info.ts @@ -7,6 +7,7 @@ export const info = (app: Assistant) => { app.handle("info__on_enter", enter); app.handle("info__intent__yes", membership); + app.handle("info__intent__no", no); app.handle("info__intent__fallback", help); app.handle("info__intent__fallback_end", missing); app.handle("info__intent__help", help); @@ -27,9 +28,16 @@ const membership: THandlerFn = (m) => { m.nextScene = "actions.scene.END_CONVERSATION"; }; +const no: THandlerFn = (m) => { + + m.say("bye.1"); + + m.nextScene = "actions.scene.END_CONVERSATION"; +}; + const help: THandlerFn = (m) => { - m.say('info.help.1', {name: NAME}); + // m.say('info.help.1', {name: NAME}); m.nextScene = "info"; } diff --git a/webhooks/functions/src/controller/handler/main.ts b/webhooks/functions/src/controller/handler/main.ts index 6d0c765a..69ecce06 100644 --- a/webhooks/functions/src/controller/handler/main.ts +++ b/webhooks/functions/src/controller/handler/main.ts @@ -21,7 +21,7 @@ export const main = (machine: TMachine) => { machine.say("main.welcome.noLinked.1", { name: NAME}); - machine.authenticationState = "NO_LINKED"; + // machine.authenticationState = "NO_LINKED"; machine.nextScene = "home_new_user"; } diff --git a/webhooks/functions/src/controller/handler/player_prequel.ts b/webhooks/functions/src/controller/handler/player_prequel.ts index 6b35850f..b37acda6 100644 --- a/webhooks/functions/src/controller/handler/player_prequel.ts +++ b/webhooks/functions/src/controller/handler/player_prequel.ts @@ -13,9 +13,17 @@ const enter: THandlerFn = async (m) => { const isPlaying = m.isCurrentlyPlaying(); + const isRegular = m.isARegularUser; + const a = m.playerCurrent.playing; + if (!isRegular || !a) { + m.say("player.explain"); + } + if (isPlaying) { m.say("player.askResumeLastOffset"); } else { + + await intro(m); m.nextScene = "player"; } m.playerCurrent.playing = true; @@ -26,6 +34,9 @@ const intro: THandlerFn = async (m) => { const {title} = await m.getCurrentPlayingTitleAndChapter(); m.say("player.start", {title}); + + + // m.say("player.start2", {title}); } const yes: THandlerFn = async (m) => { diff --git a/webhooks/functions/src/controller/handler/search.ts b/webhooks/functions/src/controller/handler/search.ts index 8650bdc2..47a4eba3 100644 --- a/webhooks/functions/src/controller/handler/search.ts +++ b/webhooks/functions/src/controller/handler/search.ts @@ -17,6 +17,7 @@ const enter: THandlerFn = (m) => { if (from === "selection__on_enter") { m.say("search.enter.2"); m.searchSession.from = 'main'; // reset + m.nextScene = "home_user"; // FIX: avoid infinite loop in gactions } else { m.say('search.enter.1'); } @@ -26,7 +27,8 @@ const enter: THandlerFn = (m) => { if (!query) { m.searchSession.state = "RUNNING"; - m.nextScene = "search"; + // m.nextScene = "search"; + m.say('search.enter.1'); return ; } diff --git a/webhooks/functions/src/controller/handler/selection.ts b/webhooks/functions/src/controller/handler/selection.ts index 27601557..73d4a96b 100644 --- a/webhooks/functions/src/controller/handler/selection.ts +++ b/webhooks/functions/src/controller/handler/selection.ts @@ -32,7 +32,7 @@ export const enter: THandlerFn = async (m) => { if (isEmpty) { if (handler === "search__on_enter") { m.say("search.empty.1", {name: NAME}); - m.nextScene = "search"; + m.nextScene = "home_user"; // FIX GACTIONS ISSUE : INFINE LOOP CONTROL m.searchSession.query = ''; m.searchSession.state = 'RUNNING'; m.searchSession.from = "selection__on_enter"; @@ -74,7 +74,7 @@ export const enter: THandlerFn = async (m) => { // @TODO handle collection group or publication // list groups or publication - m.say('selection.enter.common.1'); + m.say('selection.enter.common.1', {pageSuivante: ''}); const list = kind === "GROUP" ? (await m.getGroupsFromFeed(url)).groups.map(({title}) => title) : (await m.getPublicationFromFeed(url)).publication.map(({title}) => title); @@ -108,7 +108,7 @@ export const enter: THandlerFn = async (m) => { } else if (state === "DEFAULT" && m.playerCurrent.playing) { console.log("RUN PLAYER"); - m.nextScene = "player"; + m.nextScene = "player_prequel"; // @TODO set the next-scene to player prequel // lecture en cours ou annonciation du titre } else { @@ -157,11 +157,11 @@ const selectBook: THandlerFn = async (m) => { } else if (nb < 1) { m.selectionSession.nbChoice = 0; - m.say('selection.help.1'); + // m.say('selection.help.1'); } else if (nb > padding || nb > size) { m.selectionSession.nbChoice = 0; - m.say('selection.help.1'); + // m.say('selection.help.1'); } else { // ok let's go diff --git a/webhooks/functions/src/error.ts b/webhooks/functions/src/error.ts new file mode 100644 index 00000000..f9beba84 --- /dev/null +++ b/webhooks/functions/src/error.ts @@ -0,0 +1,5 @@ + +export class WebpubError extends Error { + + code: number; +} \ No newline at end of file diff --git a/webhooks/functions/src/sdk/collections.test.ts b/webhooks/functions/src/sdk/collections.test.ts index 4880c321..12ffbdf9 100644 --- a/webhooks/functions/src/sdk/collections.test.ts +++ b/webhooks/functions/src/sdk/collections.test.ts @@ -59,7 +59,7 @@ describe(scene + ' handler', () => { body.handler.name = 'collections__on_enter'; body.scene.name = scene; - const message = `Okay, would you prefer to get a book selection by theme or by genre ?\n`; + const message = `Okay, would you prefer to get a choice of collections by theme or by genre?\n`; const data = await expressMocked(body, headers); @@ -121,7 +121,7 @@ describe(scene + ' handler', () => { data.scene.next.name.should.to.be.eq('selection'); }); - const help = `To hear an overview of available themes, say 'theme'. For an overview of available genres, say 'genre'. Do you want to hear a list of available themes or genres ?\n`; + const help = `To hear an overview of available themes, say 'theme'. For an overview of available genres, say 'genre'. Do you want to hear a list of available themes or genres?\n`; it('help', async () => { body.handler.name = 'collections__intent__help'; @@ -152,7 +152,7 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + data.prompt.firstSimple.speech.should.to.be.eq('Bye!\n'); // data.scene.next.name.should.to.be.eq('home_new_user'); }); @@ -174,7 +174,7 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + data.prompt.firstSimple.speech.should.to.be.eq('Bye!\n'); // data.scene.next.name.should.to.be.eq('home_new_user'); }); diff --git a/webhooks/functions/src/sdk/conv.test.ts b/webhooks/functions/src/sdk/conv.test.ts index 6fcb2ba4..a0adcdb5 100644 --- a/webhooks/functions/src/sdk/conv.test.ts +++ b/webhooks/functions/src/sdk/conv.test.ts @@ -28,7 +28,7 @@ const bodyCopy = () => Object.assign({}, { 'intent': { 'name': 'actions.intent.MAIN', 'params': {}, - 'query': 'Parler avec dev edrlab', + 'query': 'Parler avec dev EDRLAB', }, 'scene': { 'name': 'actions.scene.START_CONVERSATION', @@ -42,7 +42,7 @@ const bodyCopy = () => Object.assign({}, { 'languageCode': '', }, 'user': { - 'locale': 'fr-CA', + 'locale': 'en-US', 'params': { 'bearerToken': '', }, @@ -85,7 +85,7 @@ export const convRequestInHandle = { 'intent': { 'name': 'actions.intent.MAIN', 'params': {}, - 'query': 'Parler avec dev edrlab', + 'query': 'Parler avec dev EDRLAB', }, 'scene': { 'name': 'actions.scene.START_CONVERSATION', @@ -142,7 +142,7 @@ export const convRequestInHandle = { }, 'intent': { 'name': 'actions.intent.MAIN', - 'query': 'Parler avec dev edrlab', + 'query': 'Parler avec dev EDRLAB', 'params': {}, }, 'scene': { diff --git a/webhooks/functions/src/sdk/home_new_user.test.ts b/webhooks/functions/src/sdk/home_new_user.test.ts index 56cec1f8..72ca157c 100644 --- a/webhooks/functions/src/sdk/home_new_user.test.ts +++ b/webhooks/functions/src/sdk/home_new_user.test.ts @@ -58,10 +58,11 @@ describe('home_new_user handler', () => { body.handler.name = 'home_new_user__on_enter'; body.scene.name = scene; - const message = `To fully enjoy your audiobooks and access your personal bookshelf, you will need to link your EDRLAB account.\nWould you like to do so now ?\n`; + // const message = `To fully enjoy your audiobooks and access your personal bookshelf, you will need to link your EDRLAB account.\nWould you like to do so now ?\n`; const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq(message); + data.prompt.firstSimple.speech.should.to.be.eq('To fully experience EDRLAB Library, and enjoy your favorite audiobooks via Google, you\'ll need to connect your EDRLAB account. To do so, answer \'yes\' when prompted and follow the instructions. I will then send a connection link, that you will find into the Google Home application. You will have to log in to your EDRLAB account. You\'ll only have to do this once, and you\'ll be all set to start enjoying the wonderful world of EDRLAB books for hours on end!\n' + + 'Would you like to link your account right now?\n'); }); it('repeat', async () => { body.handler.name = 'home_new_user__intent__repeat'; @@ -89,8 +90,8 @@ describe('home_new_user handler', () => { console.log(data.prompt.firstSimple); - const message = `In order to read books using the EDRLAB Library via Google, you need to be a registered EDRLAB member and link your account.\nWould you like to learn more about EDRLAB?\n`; - data.prompt.firstSimple.speech.should.to.be.eq(message); + // const message = `In order to read books using the EDRLAB Library via Google, you need to be a registered EDRLAB member and link your account.\nWould you like to learn more about EDRLAB?\n`; + // data.prompt.firstSimple.speech.should.to.be.eq(message); data.scene.next.name.should.to.be.eq('home_new_user_no'); }); @@ -99,16 +100,16 @@ describe('home_new_user handler', () => { body.handler.name = 'home_new_user__intent__maybe_later'; body.scene.name = scene; - const message = `Of course! you can learn more about EDRLAB or quit for now.\nWhat would you like to do?\n`; + // const message = `Of course! you can learn more about EDRLAB or quit for now.\nWhat would you like to do?\n`; const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq(message); + // data.prompt.firstSimple.speech.should.to.be.eq(message); data.scene.next.name.should.to.be.eq('home_new_user_maybe_later'); }); - const help = `To fully experience EDRLAB Library, and enjoy your favorite audiobooks via Google, you'll need to connect your CELA account. To do so, answer 'yes' when prompted and follow the instructions. I will then send a connection link, that you will find into the Google Home application. You will have to log in to your EDRLAB account. You'll only have to do this once, and you'll be all set to start enjoying the wonderful world of EDRLAB books for hours on end!\nWould you like to link your account right now?\n`; + // const help = `To fully experience EDRLAB Library, and enjoy your favorite audiobooks via Google, you'll need to connect your EDRLAB account. To do so, answer 'yes' when prompted and follow the instructions. I will then send a connection link, that you will find into the Google Home application. You will have to log in to your EDRLAB account. You'll only have to do this once, and you'll be all set to start enjoying the wonderful world of EDRLAB books for hours on end!\nWould you like to link your account right now?\n`; it('help', async () => { body.handler.name = 'home_new_user__intent__help'; @@ -117,7 +118,7 @@ describe('home_new_user handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq(help); + // data.prompt.firstSimple.speech.should.to.be.eq(help); data.scene.next.name.should.to.be.eq('home_new_user'); }); @@ -128,7 +129,7 @@ describe('home_new_user handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq(help); + // data.prompt.firstSimple.speech.should.to.be.eq(help); data.scene.next.name.should.to.be.eq('home_new_user'); }); @@ -139,7 +140,7 @@ describe('home_new_user handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + data.prompt.firstSimple.speech.should.to.be.eq('Bye!\n'); // data.scene.next.name.should.to.be.eq('home_new_user'); }); @@ -150,7 +151,7 @@ describe('home_new_user handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq(help); + // data.prompt.firstSimple.speech.should.to.be.eq(help); data.scene.next.name.should.to.be.eq('home_new_user'); }); @@ -161,7 +162,7 @@ describe('home_new_user handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + data.prompt.firstSimple.speech.should.to.be.eq('Bye!\n'); // data.scene.next.name.should.to.be.eq('home_new_user'); }); diff --git a/webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts b/webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts index fdae5ef9..13e57160 100644 --- a/webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts +++ b/webhooks/functions/src/sdk/home_new_user_maybe_later.test.ts @@ -57,7 +57,7 @@ describe('home_new_user_maybe_later handler', () => { body.handler.name = 'home_new_user_maybe_later__on_enter'; body.scene.name = scene; - const message = `Of course! you can learn more about EDRLAB or quit for now.\nWhat would you like to do?\n`; + const message = `You can ask me to link your account, or learn more about the EDRLAB Library. You can also exit this application, by simply saying 'stop'. What is your decision?\n`; const data = await expressMocked(body, headers); @@ -78,8 +78,8 @@ describe('home_new_user_maybe_later handler', () => { const data = await expressMocked(body, headers); - const message = `EDRLAB about text. Would you like to find out more about EDRLAB membership, or would you prefer to exit this skill?\n`; - data.prompt.firstSimple.speech.should.to.be.eq(message); + // const message = `EDRLAB about text. Would you like to find out more about EDRLAB membership, or would you prefer to exit this skill?\n`; + // data.prompt.firstSimple.speech.should.to.be.eq(message); data.scene.next.name.should.to.be.eq('info'); }); @@ -88,12 +88,12 @@ describe('home_new_user_maybe_later handler', () => { body.handler.name = 'home_new_user_maybe_later__intent__repeat'; body.scene.name = scene; - const data = await expressMocked(body, headers); + // const data = await expressMocked(body, headers); - data.scene.next.name.should.to.be.eq('home_new_user_maybe_later'); + // data.scene.next.name.should.to.be.eq('home_new_user_maybe_later'); }); - const help = `You can ask me to link your account, or to learn more about EDRLAB. You can also exit this skill, by simply saying 'stop'. What would you like to do?\n`; + // const help = `You can ask me to link your account, or to learn more about EDRLAB. You can also exit this skill, by simply saying 'stop'. What would you like to do?\n`; it('help', async () => { body.handler.name = 'home_new_user_maybe_later__intent__help'; @@ -102,7 +102,7 @@ describe('home_new_user_maybe_later handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq(help); + // data.prompt.firstSimple.speech.should.to.be.eq(help); data.scene.next.name.should.to.be.eq('home_new_user_maybe_later'); }); @@ -113,7 +113,7 @@ describe('home_new_user_maybe_later handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq(help); + // data.prompt.firstSimple.speech.should.to.be.eq(help); data.scene.next.name.should.to.be.eq('home_new_user_maybe_later'); }); @@ -124,7 +124,7 @@ describe('home_new_user_maybe_later handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + data.prompt.firstSimple.speech.should.to.be.eq('Bye!\n'); // data.scene.next.name.should.to.be.eq('home_new_user'); }); @@ -135,7 +135,7 @@ describe('home_new_user_maybe_later handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq(help); + // data.prompt.firstSimple.speech.should.to.be.eq(help); data.scene.next.name.should.to.be.eq('home_new_user_maybe_later'); }); @@ -146,7 +146,7 @@ describe('home_new_user_maybe_later handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + data.prompt.firstSimple.speech.should.to.be.eq('Bye!\n'); // data.scene.next.name.should.to.be.eq('home_new_user'); }); diff --git a/webhooks/functions/src/sdk/home_new_user_no.test.ts b/webhooks/functions/src/sdk/home_new_user_no.test.ts index b835885e..d114b137 100644 --- a/webhooks/functions/src/sdk/home_new_user_no.test.ts +++ b/webhooks/functions/src/sdk/home_new_user_no.test.ts @@ -57,7 +57,7 @@ describe(scene + ' handler', () => { body.handler.name = 'home_new_user_no__on_enter'; body.scene.name = scene; - const message = `In order to read books using the EDRLAB Library via Google, you need to be a registered EDRLAB member and link your account.\nWould you like to learn more about EDRLAB?\n`; + const message = `In order to read books using the EDRLAB Library via Google, you need to be a registered EDRLAB member and link your account.\nWould you like to learn more about registering on the EDRLAB Library?\n`; const data = await expressMocked(body, headers); data.prompt.firstSimple.speech.should.to.be.eq(message); @@ -68,8 +68,8 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers); - const message = `EDRLAB about text. Would you like to find out more about EDRLAB membership, or would you prefer to exit this skill?\n`; - data.prompt.firstSimple.speech.should.to.be.eq(message); + // const message = `EDRLAB is a national non-profit organization established by Canadian public libraries to champion the fundamental right of Canadians with print disabilities to access media and reading materials in the format of their choice, including audio, braille, e-text and descriptive video. Would you like to find out more about EDRLAB membership, or would you prefer to exit this skill?\n`; + // data.prompt.firstSimple.speech.should.to.be.eq(message); data.scene.next.name.should.to.be.eq('info'); }); @@ -92,7 +92,7 @@ describe(scene + ' handler', () => { data.scene.next.name.should.to.be.eq('home_new_user_no'); }); - const help = `If you'd like to learn more about EDRLAB. You can ask me by saying 'what is EDRLAB', or simply say 'stop' to exit this app. If you have any other questions, we recommend reaching out to your local library for support. Do you want to learn more about EDRLAB or exit this app?\n`; + const help = `In order to use the EDRLAB library via your Google Home, you must be a registered member of the library and link your account. Would you like to learn more about the EDRLAB Livrary?\n`; it('help', async () => { body.handler.name = 'home_new_user_no__intent__help'; @@ -123,7 +123,7 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + data.prompt.firstSimple.speech.should.to.be.eq('Bye!\n'); // data.scene.next.name.should.to.be.eq('home_new_user_no'); }); @@ -145,7 +145,7 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + data.prompt.firstSimple.speech.should.to.be.eq('Bye!\n'); // data.scene.next.name.should.to.be.eq('home_new_user_no'); }); diff --git a/webhooks/functions/src/sdk/home_user.test.ts b/webhooks/functions/src/sdk/home_user.test.ts index 709cb47d..200b14ee 100644 --- a/webhooks/functions/src/sdk/home_user.test.ts +++ b/webhooks/functions/src/sdk/home_user.test.ts @@ -27,6 +27,9 @@ const yaml = `intentEvents: - handler: webhookHandler: home_user__intent__search intent: search +- handler: + webhookHandler: home_user__intent__recent_books + intent: recent_books - handler: webhookHandler: home_user__intent__fallback intent: actions.intent.NO_MATCH_1 @@ -64,7 +67,7 @@ describe('home_user handler', () => { body.scene.name = scene; body.session.id = 'on enter'; // new session - const message = `Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?\n`; + const message = 'Would you like to consult your bookshelf, or browse our collections? You can also search for a book by saying search followed by a book title or an author.\n'; const data = await expressMocked(body, headers); data.prompt.firstSimple.speech.should.to.be.eq(message); @@ -74,12 +77,12 @@ describe('home_user handler', () => { body.scene.name = scene; body.session.id = 'id'; // new session - const message = `Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?\n`; + const message = 'Would you like to consult your bookshelf, or browse our collections? You can also search for a book by saying search followed by a book title or an author.\n'; const pullData = parsedDataClone(); const model = await storageModelMocked(pullData); const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); - model.data.store.session.scene.home_user.state.should.not.to.be.eq('SESSION'); + model.data.store.session.scene.home_user.state.should.to.be.eq('SESSION'); data.prompt.firstSimple.speech.should.to.be.eq(message); }); it('on enter with session state but new session undefined so the session data is not removed', async () => { @@ -87,12 +90,12 @@ describe('home_user handler', () => { body.scene.name = scene; body.session.id = 'on enter with session state but new session undefined so the session data is not removed'; // new session - const message = `Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?\n`; + const message = 'Would you like to consult your bookshelf, or browse our collections? You can also search for a book by saying search followed by a book title or an author.\n'; const pullData = parsedDataClone(); const model = await storageModelMocked(pullData); const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); - model.data.store.session.scene.home_user.state.should.not.to.be.eq('SESSION'); + model.data.store.session.scene.home_user.state.should.to.be.eq('SESSION'); data.prompt.firstSimple.speech.should.to.be.eq(message); }); it('on enter with session state', async () => { @@ -100,7 +103,7 @@ describe('home_user handler', () => { body.scene.name = scene; body.session.id = 'test'; - const message = `What would you like to do?\n`; + const message = 'Would you like to consult your bookshelf, or browse our collections? You can also search for a book by saying search followed by a book title or an author.\n'; const pullData = parsedDataClone(); const model = await storageModelMocked(pullData); @@ -113,7 +116,6 @@ describe('home_user handler', () => { body.scene.name = scene; body.session.id = 'on enter with a current playing no history'; - const message = `Last time, you read Chapter 10 of my title, hello, which you can resume where you left off.\nYou can search for a new one alltogether.\nWhat would you like to do?\n`; const pullData = parsedDataClone(); pullData.player.current.index = 9; pullData.player.current.url = 'https://my.url'; @@ -132,14 +134,16 @@ describe('home_user handler', () => { const data = await expressMocked(body, headers, pullData, undefined, webpub); console.log(JSON.stringify(data, null, 4)); - data.prompt.firstSimple.speech.should.to.be.eq(message); + data.prompt.firstSimple.speech.should.to.be.eq('You are listening to the 10 chapter of my title, hello, which you can pick up where you left off.\n' + + 'But there is more:\n' + + 'You can consult your bookshelf, or browse our collections. You can also search for a book by saying search followed by a book title or an author.\n' + + 'Resume reading. Recent books. Bookshelf. Collections. Search for a specific book: what do you want to do?\n'); }); it('on enter with a current playing and history', async () => { body.handler.name = 'home_user__on_enter'; body.scene.name = scene; body.session.id = 'on enter with a current playing and history'; - const message = `Last time, you read Chapter 10 of my title, hello, which you can resume where you left off.\nYou are also reading 4 other recent books, which you can choose from.\nYou can search for a new one alltogether.\nWhat would you like to do?\n`; const pullData = parsedDataClone(); pullData.player.current.index = 9; pullData.player.current.url = 'https://my.url'; @@ -169,7 +173,11 @@ describe('home_user handler', () => { const data = await expressMocked(body, headers, pullData, undefined, webpub); console.log(JSON.stringify(data, null, 4)); - data.prompt.firstSimple.speech.should.to.be.eq(message); + data.prompt.firstSimple.speech.should.to.be.eq('You are listening to the 10 chapter of my title, hello, which you can pick up where you left off.\n' + + 'You are also reading 3 other recent books, which you can choose from.\n' + + 'But there is more:\n' + + 'You can consult your bookshelf, or browse our collections. You can also search for a book by saying search followed by a book title or an author.\n' + + 'Resume reading. Recent books. Bookshelf. Collections. Search for a specific book: what do you want to do?\n'); }); it('repeat', async () => { @@ -218,6 +226,45 @@ describe('home_user handler', () => { data.scene.next.name.should.to.be.eq('search'); }); + it('recents book', async () => { + body.handler.name = 'home_user__intent__recent_books'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + pullData.player.current.index = 9; + pullData.player.current.url = 'https://my.url'; + pullData.player.current.time = 0; + pullData.player.current.playing = true; + + pullData.player.history = { + // @ts-ignore + 1: {index: 0, time: 0, date: new Date()}, + 2: {index: 0, time: 0, date: new Date()}, + 3: {index: 0, time: 0, date: new Date()}, + 4: {index: 0, time: 0, date: new Date()}, + }; + // pullData.player.history.set("1", {index: 0, time: 0, date: new Date()}); + // pullData.player.history.set("2", {index: 0, time: 0, date: new Date()}); + // pullData.player.history.set("3", {index: 0, time: 0, date: new Date()}); + // pullData.player.history.set("4", {index: 0, time: 0, date: new Date()}); + const model = await storageModelMocked(pullData); + + const webpub: Partial = { + title: 'my title', + authors: [ + 'hello', + 'world', + ], + }; + + const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); + + data.scene.next.name.should.to.be.eq('selection'); + model.data.store.session.scene.selection.url.should.to.be.eq('data://["1","2","3"]'); + model.data.store.session.scene.selection.kind.should.to.be.eq('PUBLICATION'); + model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); + }); + it('browse collections', async () => { body.handler.name = 'home_user__intent__collections'; body.scene.name = scene; @@ -246,7 +293,7 @@ describe('home_user handler', () => { data.scene.next.name.should.to.be.eq('selection'); }); - const help = `You can search for a specific book by title or author, browse our collections or check your bookshelf to start reading one of your preselected books.\nWhat would you like to do?\n`; + // const help = `You can search for a specific book by title or author, browse our collections or check your bookshelf to start reading one of your preselected books.\nWhat would you like to do?\n`; it('help', async () => { body.handler.name = 'home_user__intent__help'; @@ -254,7 +301,7 @@ describe('home_user handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq(help); + // data.prompt.firstSimple.speech.should.to.be.eq(help); data.scene.next.name.should.to.be.eq('home_user'); }); @@ -265,7 +312,7 @@ describe('home_user handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq(help); + // data.prompt.firstSimple.speech.should.to.be.eq(help); data.scene.next.name.should.to.be.eq('home_user'); }); @@ -276,7 +323,7 @@ describe('home_user handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + data.prompt.firstSimple.speech.should.to.be.eq('Bye!\n'); // data.scene.next.name.should.to.be.eq('home_user'); }); @@ -287,7 +334,7 @@ describe('home_user handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq(help); + // data.prompt.firstSimple.speech.should.to.be.eq(help); data.scene.next.name.should.to.be.eq('home_user'); }); @@ -298,7 +345,7 @@ describe('home_user handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + data.prompt.firstSimple.speech.should.to.be.eq('Bye!\n'); // data.scene.next.name.should.to.be.eq('home_user'); }); diff --git a/webhooks/functions/src/sdk/info.test.ts b/webhooks/functions/src/sdk/info.test.ts index 85420f37..84fbe4a4 100644 --- a/webhooks/functions/src/sdk/info.test.ts +++ b/webhooks/functions/src/sdk/info.test.ts @@ -23,6 +23,9 @@ const yaml = `intentEvents: webhookHandler: info__intent__yes intent: membership transitionToScene: actions.scene.END_CONVERSATION +- handler: + webhookHandler: info__intent__no + intent: "no" - handler: webhookHandler: info__intent__fallback intent: actions.intent.NO_MATCH_1 @@ -59,11 +62,11 @@ describe(scene + ' handler', () => { body.handler.name = 'info__on_enter'; body.scene.name = scene; - const message = `EDRLAB about text. Would you like to find out more about EDRLAB membership, or would you prefer to exit this skill?\n`; + // const message = `EDRLAB about text. Would you like to find out more about EDRLAB membership, or would you prefer to exit this skill?\n`; - const data = await expressMocked(body, headers); + await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq(message); + // data.prompt.firstSimple.speech.should.to.be.eq(message); }); it('yes or membership', async () => { body.handler.name = 'info__intent__yes'; @@ -71,12 +74,23 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers); - const message = `Signing up is easy, you can head on over to the CELA online platform at 'URL'. Keep the name of your local library and your library or SQLA number handy, that's all you'll need. You can also ask for help at your local library. As soon as your membership is activated, you can come back to start using the EDRLAB library via Alexa, by saying 'Hey Google, launch EDRLAB'\n`; + const message = `Signing up is easy, you can head on over to the CELA online platform at CELA Library dot c.a. Keep the name of your local library and your library or SQLA number handy, that's all you'll need. You can also ask for help at your local library. As soon as your membership is activated, you can come back to start using the EDRLAB library via Google Assistant, by saying 'Hey Google, launch Accessible reading Canada.\n`; data.prompt.firstSimple.speech.should.to.be.eq(message); data.scene.next.name.should.to.be.eq('actions.scene.END_CONVERSATION'); }); + it('no', async () => { + body.handler.name = 'info__intent__yes'; + body.scene.name = scene; + + const data = await expressMocked(body, headers); + + // data.prompt.firstSimple.speech.should.to.be.eq(message); + + data.scene.next.name.should.to.be.eq('actions.scene.END_CONVERSATION'); + }); + it('repeat', async () => { body.handler.name = 'info__intent__repeat'; body.scene.name = scene; @@ -86,7 +100,7 @@ describe(scene + ' handler', () => { data.scene.next.name.should.to.be.eq('info'); }); - const help = `If you'd like to learn more about EDRLAB membership - you can ask me by saying 'membership', or simply say 'stop' to exit this skill. If you have any other questions, we recommend reaching out to your local library for support. I'm listening?\n`; + // const help = `If you'd like to learn more about EDRLAB membership - you can ask me by saying 'membership', or simply say 'stop' to exit this skill. If you have any other questions, we recommend reaching out to your local library for support. I'm listening?\n`; it('help', async () => { body.handler.name = 'info__intent__help'; @@ -95,7 +109,7 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq(help); + // data.prompt.firstSimple.speech.should.to.be.eq(help); data.scene.next.name.should.to.be.eq('info'); }); @@ -106,7 +120,7 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq(help); + // data.prompt.firstSimple.speech.should.to.be.eq(help); data.scene.next.name.should.to.be.eq('info'); }); @@ -117,7 +131,7 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + data.prompt.firstSimple.speech.should.to.be.eq('Bye!\n'); // data.scene.next.name.should.to.be.eq('home_new_user'); }); @@ -128,7 +142,7 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq(help); + // data.prompt.firstSimple.speech.should.to.be.eq(help); data.scene.next.name.should.to.be.eq('info'); }); @@ -139,7 +153,7 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + data.prompt.firstSimple.speech.should.to.be.eq('Bye!\n'); // data.scene.next.name.should.to.be.eq('home_new_user'); }); diff --git a/webhooks/functions/src/sdk/main.test.ts b/webhooks/functions/src/sdk/main.test.ts index 16a05f36..ebaa610c 100644 --- a/webhooks/functions/src/sdk/main.test.ts +++ b/webhooks/functions/src/sdk/main.test.ts @@ -1,7 +1,8 @@ -import {expressMocked, shell} from '../test/utils.test'; +import {expressMocked, shell, storageModelMocked} from '../test/utils.test'; import * as chai from 'chai'; // import * as sinon from 'sinon'; import {headers, body} from './conv.test'; +import {parsedDataClone} from '../model/data.model.test'; chai.should(); @@ -19,7 +20,7 @@ describe('main handler', () => { body.user.accountLinkingStatus = 'ACCOUNT_LINKING_STATUS_UNSPECIFIED'; const data = await expressMocked(body, headers); - const welcomeNewUser = 'Welcome to EDRLAB Library!\n'; + const welcomeNewUser = 'Welcome to EDRLAB Library, where you can easily access your favorite audio books.\n'; data.prompt.firstSimple.speech.should.to.be.eq(welcomeNewUser); @@ -27,10 +28,10 @@ describe('main handler', () => { }); it('main new user not linked', async () => { - body.user.accountLinkingStatus = 'NOT_LINKED'; + body.user.accountLinkingStatus = 'NO_LINKED'; const data = await expressMocked(body, headers); - const welcomeNewUser = 'Welcome to EDRLAB Library!\n'; + const welcomeNewUser = 'Welcome to EDRLAB Library, where you can easily access your favorite audio books.\n'; data.prompt.firstSimple.speech.should.to.be.eq(welcomeNewUser); @@ -39,12 +40,31 @@ describe('main handler', () => { it('main new user linked', async () => { body.user.accountLinkingStatus = 'LINKED'; - const data = await expressMocked(body, headers); - const welcomeUser = 'Welcome back to your EDRLAB Library!\n'; + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + + const welcomeUser = 'Welcome back to your EDRLAB Library! Remember, you can ask for help at any time.\n'; + + data.prompt.firstSimple.speech.should.to.be.eq(welcomeUser); + + model.data.store.user.authentication.should.to.be.eq('NEWLY_LINKED'); + data.scene.next.name.should.to.be.eq('home_user'); + }); + it('main user linked', async () => { + body.user.accountLinkingStatus = 'LINKED'; + + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + model.data.store.user.authentication = 'NEWLY_LINKED'; + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + + const welcomeUser = 'Welcome back to your EDRLAB Library! Remember, you can ask for help at any time.\n'; data.prompt.firstSimple.speech.should.to.be.eq(welcomeUser); + model.data.store.user.authentication.should.to.be.eq('LINKED'); data.scene.next.name.should.to.be.eq('home_user'); }); }); diff --git a/webhooks/functions/src/sdk/player_prequel.test.ts b/webhooks/functions/src/sdk/player_prequel.test.ts index 3f2a0d2e..2031f97e 100644 --- a/webhooks/functions/src/sdk/player_prequel.test.ts +++ b/webhooks/functions/src/sdk/player_prequel.test.ts @@ -86,12 +86,11 @@ describe(scene + ' handler', () => { ], }; - const message = 'Do you want to pick up where it left off ?\n'; - const model = await storageModelMocked(pullData); const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); - data.prompt.firstSimple.speech.should.to.be.eq(message); + data.prompt.firstSimple.speech.should.to.be.eq('Great choice! Before we start, let me remind you how this reader works. You can put your read on hold at any time by saying \'Hey Google, Pause\'. \'Hey Google, Resume\' will let you pick up your reading where you last left it. You can also navigate between chapters by saying \'Hey Google, next\' or \'Hey Google, previous\' at any time. Now, shall we get started with \'A Slow Fire Burning\'?\n' + + 'Do you want to pick up where it left off?\n'); }); it('no', async () => { diff --git a/webhooks/functions/src/sdk/search.test.ts b/webhooks/functions/src/sdk/search.test.ts index ed3d1889..a3da91b9 100644 --- a/webhooks/functions/src/sdk/search.test.ts +++ b/webhooks/functions/src/sdk/search.test.ts @@ -68,7 +68,7 @@ describe(scene + ' handler', () => { body.handler.name = 'search__on_enter'; body.scene.name = scene; - const message = `In the meanwhile, is there another title or author you'd like to search for ?\n`; + const message = `In the meanwhile, is there another title or author you'd like to search for?\n`; const pullData = parsedDataClone(); diff --git a/webhooks/functions/src/sdk/selection.test.ts b/webhooks/functions/src/sdk/selection.test.ts index fd1db4d0..0e6fd656 100644 --- a/webhooks/functions/src/sdk/selection.test.ts +++ b/webhooks/functions/src/sdk/selection.test.ts @@ -4,6 +4,7 @@ import * as chai from 'chai'; import {headers, body} from './conv.test'; import {parsedDataClone} from '../model/data.model.test'; import {IOpdsResultView} from 'opds-fetcher-parser/build/src/interface/opds'; +import {IWebPubView} from 'opds-fetcher-parser/build/src/interface/webpub'; chai.should(); @@ -54,13 +55,13 @@ describe(scene + ' handler', () => { }); const messageHelpers = (number: number, it: Array<[nb: number, title: string]>) => { - const a = 'Pick one of these by saying their numbers.\n'; + const a = 'Pick one of these by requesting the corresponding number, or ask for the next set.\n'; const b = it.reduce((pv, [nb, title]) => pv + `${nb}. ${title}\n`, ''); - const c = 'Which one would you like to start reading?\n'; + const c = 'Which one will you choose?\n'; return a + b + c; }; - const help = `Pick one out of 3 titles by mentioning their numbers. You can also ask for 'another one'.\n`; // What would you like to do?\n`; + const help = 'At this stage, you must choose a title among the proposed set, by mentioning its number, for example number 1. You can request other titles by using the Next or Previous commands.\n'; describe('app', () => { it('on enter', async () => { @@ -233,9 +234,9 @@ describe(scene + ' handler', () => { ], }; const message = messageHelpers(3, [ - [1, 'first publication'], - [2, 'second publication'], - [3, 'third publication'], + [1, 'first publication.'], + [2, 'second publication.'], + [3, 'third publication.'], ]); return {pullData, feed, message}; @@ -269,9 +270,9 @@ describe(scene + ' handler', () => { ], }; const message = messageHelpers(3, [ - [1, 'first group'], - [2, 'second group'], - [3, 'third group'], + [1, 'first group.'], + [2, 'second group.'], + [3, 'third group.'], ]); return {pullData, feed, message}; @@ -331,7 +332,7 @@ describe(scene + ' handler', () => { model.data.store.session.scene.search.from.should.to.be.eq('selection__on_enter'); model.data.store.session.scene.search.query.should.to.be.eq(''); model.data.store.session.scene.search.state.should.to.be.eq('RUNNING'); - data.scene.next.name.should.to.be.eq('search'); + data.scene.next.name.should.to.be.eq('home_user'); }); it('on enter - state running - publication list first page with no next link', async () => { @@ -440,7 +441,7 @@ describe(scene + ' handler', () => { const {pullData, feed, message} = testStateRunningPublication(); pullData.session.scene.selection.nextUrlCounter = 0; - pullData.session.scene.selection.from = 'home_user__intent__bookshelf', + pullData.session.scene.selection.from = 'home_user__intent__bookshelf'; // @ts-ignore feed.links = { next: [ @@ -457,6 +458,86 @@ describe(scene + ' handler', () => { // data.scene.next.name.should.to.be.eq('selection'); }); + it('on enter - state running - recent books', async () => { + body.handler.name = 'selection__on_enter'; + body.scene.name = scene; + + const {pullData, feed} = testStateRunningPublication(); + pullData.session.scene.selection.nextUrlCounter = 0; + pullData.session.scene.selection.state = 'RUNNING'; + pullData.session.scene.selection.kind = 'PUBLICATION'; + pullData.session.scene.selection.url = 'data://["https://my.url","https://my.url","https://my.url"]'; + pullData.session.scene.selection.from = 'home_user__intent__recent_books'; + + const webpub: Partial = { + title: 'my test title', + authors: ['author'], + }; + + const data = await expressMocked(body, headers, pullData, feed, webpub); + + data.prompt.firstSimple.speech.should.to.be.eq('Pick one of these by requesting the corresponding number, or ask for the next set.\n' + + '1. my test title.\n' + + '2. my test title.\n' + + '3. my test title.\n' + + 'Which one will you choose?\n'); + // data.scene.next.name.should.to.be.eq('selection'); + }); + it('on_enter - groups - state == DEFAULT should throw', async () => { + body.handler.name = 'selection__on_enter'; + body.scene.name = scene; + // body.intent.params = { + // number: { + // original: '3', + // resolved: 3, + // }, + // }; + + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + model.data.store.session.scene.selection.kind = 'GROUP'; + model.data.store.session.scene.selection.url = 'http://my.url'; + model.data.store.session.scene.selection.nbChoice = 3; + const feed = newFeed(); + feed.publications?.length.should.to.be.eq(2); + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); + + // THROWS !! + + data.scene.next.name.should.to.be.eq('actions.scene.END_CONVERSATION'); + model.data.store.session.scene.selection.state.should.to.be.eq('DEFAULT'); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(3); + data.prompt.firstSimple.speech.should.to.be.eq('Oops, something went wrong. I will exit the app. Feel free to reopen it as soon as possible.'); + }); + + it('on_enter - pub - state == DEFAULT should throw', async () => { + body.handler.name = 'selection__on_enter'; + body.scene.name = scene; + // body.intent.params = { + // number: { + // original: '3', + // resolved: 3, + // }, + // }; + + const pullData = parsedDataClone(); + const model = await storageModelMocked(pullData); + model.data.store.session.scene.selection.kind = 'PUBLICATION'; + model.data.store.session.scene.selection.url = 'http://my.url'; + model.data.store.session.scene.selection.nbChoice = 0; + const feed = newFeed(); + feed.publications?.length.should.to.be.eq(2); + const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); + + // THROWS !! + + data.scene.next.name.should.to.be.eq('actions.scene.END_CONVERSATION'); + model.data.store.session.scene.selection.state.should.to.be.eq('DEFAULT'); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); + data.prompt.firstSimple.speech.should.to.be.eq('Oops, something went wrong. I will exit the app. Feel free to reopen it as soon as possible.'); + }); + + // @TODO // complete the test from handler // it('on enter - state running - group list last with next page - from collection', async () => { @@ -501,7 +582,7 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); - data.scene.next.name.should.to.be.eq('player'); + data.scene.next.name.should.to.be.eq('player_prequel'); model.data.store.session.scene.selection.state.should.to.be.eq('DEFAULT'); model.data.store.session.scene.selection.url.should.to.be.eq(''); model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); @@ -528,7 +609,7 @@ describe(scene + ' handler', () => { feed.publications?.length.should.to.be.eq(2); const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); - data.scene.next.name.should.to.be.eq('player'); + data.scene.next.name.should.to.be.eq('player_prequel'); model.data.store.session.scene.selection.state.should.to.be.eq('DEFAULT'); model.data.store.session.scene.selection.url.should.to.be.eq(''); model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); @@ -559,9 +640,10 @@ describe(scene + ' handler', () => { data.scene.next.name.should.to.be.eq('selection'); model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); + (typeof data.prompt.firstSimple).should.to.be.eq('undefined'); }); - it('select book - state == DEFAULT should throw', async () => { + it('select book - state == DEFAULT should throw in on_enter instead of select_books', async () => { body.handler.name = 'selection__intent__selects_book'; body.scene.name = scene; body.intent.params = { @@ -581,10 +663,11 @@ describe(scene + ' handler', () => { // THROWS !! - data.scene.next.name.should.to.be.eq('actions.scene.END_CONVERSATION'); + data.scene.next.name.should.to.be.eq('selection'); model.data.store.session.scene.selection.state.should.to.be.eq('DEFAULT'); model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); - data.prompt.firstSimple.speech.should.to.be.eq('Oops, something went wrong. I will exit the app. Feel free to reopen it as soon as possible.'); + // data.prompt.firstSimple.speech.should.to.be.eq('Oops, something went wrong. I will exit the app. Feel free to reopen it as soon as possible.'); + (typeof data.prompt.firstSimple).should.to.be.eq('undefined'); }); it('select book - number 10', async () => { @@ -606,11 +689,8 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); data.scene.next.name.should.to.be.eq('selection'); - data.prompt.firstSimple.speech.should.to.be.eq('Pick one out of 3 titles by mentioning their numbers. You can also ask for \'another one\'.\n' + - 'Pick one of these by saying their numbers.\n' + - '1. first publication\n' + - '2. second publication\n' + - 'Which one would you like to start reading?\n'); + // must be set in selection__on_enter not here : return all logics to on_enter + (typeof data.prompt.firstSimple).should.to.be.eq('undefined'); model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); // equals to original state model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); // reset // or @@ -689,15 +769,18 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); data.scene.next.name.should.to.be.eq('selection'); - data.prompt.firstSimple.speech.should.to.be.eq('Pick one out of 3 titles by mentioning their numbers. You can also ask for \'another one\'.\n' + - 'Pick one of these by saying their numbers.\n' + - '1. first group\n' + - '2. second group\n' + - 'Which one would you like to start reading?\n'); + + // must be set in selection__on_enter not here : return all logics to on_enter + (typeof data.prompt.firstSimple).should.to.be.eq('undefined'); + // data.prompt.firstSimple.speech.should.to.be.eq('Pick one out of 3 titles by mentioning their numbers. You can also ask for \'another one\'.\n' + + // 'Pick one of these by saying their numbers.\n' + + // '1. first group.\n' + + // '2. second group.\n' + + // 'Which one would you like to start reading?\n'); model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); // equals to original state model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); // reset }); - it('select book - group - state == DEFAULT should throw', async () => { + it('select book - group - state == DEFAULT should throw on selection on_enter not in select_books', async () => { body.handler.name = 'selection__intent__selects_book'; body.scene.name = scene; body.intent.params = { @@ -717,10 +800,11 @@ describe(scene + ' handler', () => { // THROWS !! - data.scene.next.name.should.to.be.eq('actions.scene.END_CONVERSATION'); + data.scene.next.name.should.to.be.eq('selection'); model.data.store.session.scene.selection.state.should.to.be.eq('DEFAULT'); model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); - data.prompt.firstSimple.speech.should.to.be.eq('Oops, something went wrong. I will exit the app. Feel free to reopen it as soon as possible.'); + // data.prompt.firstSimple.speech.should.to.be.eq('Oops, something went wrong. I will exit the app. Feel free to reopen it as soon as possible.'); + (typeof data.prompt.firstSimple).should.to.be.eq('undefined'); }); it('select book - group - number 10', async () => { @@ -742,11 +826,13 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); data.scene.next.name.should.to.be.eq('selection'); - data.prompt.firstSimple.speech.should.to.be.eq('Pick one out of 3 titles by mentioning their numbers. You can also ask for \'another one\'.\n' + - 'Pick one of these by saying their numbers.\n' + - '1. first group\n' + - '2. second group\n' + - 'Which one would you like to start reading?\n'); + // must be set in selection__on_enter not here : return all logics to on_enter + (typeof data.prompt.firstSimple).should.to.be.eq('undefined'); + // data.prompt.firstSimple.speech.should.to.be.eq('Pick one out of 3 titles by mentioning their numbers. You can also ask for \'another one\'.\n' + + // 'Pick one of these by saying their numbers.\n' + + // '1. first group.\n' + + // '2. second group.\n' + + // 'Which one would you like to start reading?\n'); model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); // equals to original state model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); // reset // or @@ -979,7 +1065,7 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + data.prompt.firstSimple.speech.should.to.be.eq('Bye!\n'); // data.scene.next.name.should.to.be.eq('home_new_user'); }); @@ -1001,7 +1087,7 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers); - data.prompt.firstSimple.speech.should.to.be.eq('need to replace this message\n'); + data.prompt.firstSimple.speech.should.to.be.eq('Bye!\n'); // data.scene.next.name.should.to.be.eq('home_new_user'); }); diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index ac58152c..e5eaf11b 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -2,10 +2,10 @@ "main": { "welcome": { "noLinked": { - "1": "Welcome to {{- name}} Library!" + "1": "Welcome to {{- name}} Library, where you can easily access your favorite audio books." }, "linked": { - "1": "Welcome back to your {{- name}} Library!" + "1": "Welcome back to your {{- name}} Library! Remember, you can ask for help at any time." } } }, @@ -18,61 +18,63 @@ }, "no": { "1": "In order to read books using the {{- name}} Library via Google, you need to be a registered {{- name}} member and link your account.", - "2": "Would you like to learn more about {{- name}}?" + "2": "Would you like to learn more about registering on the {{- name}} Library?" }, "help": { - "1": "To fully experience {{- name}} Library, and enjoy your favorite audiobooks via Google, you'll need to connect your CELA account. To do so, answer 'yes' when prompted and follow the instructions. I will then send a connection link, that you will find into the Google Home application. You will have to log in to your {{- name}} account. You'll only have to do this once, and you'll be all set to start enjoying the wonderful world of {{- name}} books for hours on end!", + "1": "To fully experience {{- name}} Library, and enjoy your favorite audiobooks via Google, you'll need to connect your {{- name}} account. To do so, answer 'yes' when prompted and follow the instructions. I will then send a connection link, that you will find into the Google Home application. You will have to log in to your {{- name}} account. You'll only have to do this once, and you'll be all set to start enjoying the wonderful world of {{- name}} books for hours on end!", "2": "Would you like to link your account right now?" }, "maybeLater": { - "1": "Of course! you can learn more about {{- name}} or quit for now.", + "1": "In order to use the {{- name}} Library via your Google Home, you must be a registered member of {{- name}} and link your account. In the meanwhile, you can learn more about {{- name}} or quit for now.", "2": "What would you like to do?" } }, "home_new_user_maybe_later": { "help": { - "1": "You can ask me to link your account, or to learn more about {{- name}}. You can also exit this skill, by simply saying 'stop'. What would you like to do?" + "1": "You can ask me to link your account, or learn more about the {{- name}} Library. You can also exit this application, by simply saying 'stop'. What is your decision?" } }, "home_new_user_no": { "help": { - "1": "If you'd like to learn more about {{- name}}. You can ask me by saying 'what is {{- name}}', or simply say 'stop' to exit this app. If you have any other questions, we recommend reaching out to your local library for support. Do you want to learn more about {{- name}} or exit this app?" + "1": "In order to use the {{- name}} library via your Google Home, you must be a registered member of the library and link your account. Would you like to learn more about the {{- name}} Livrary?" } }, "info": { "about": { - "1": "{{- name}} about text. Would you like to find out more about {{- name}} membership, or would you prefer to exit this skill?" + "1": "{{- name}} is a national non-profit organization established by Canadian public libraries to champion the fundamental right of Canadians with print disabilities to access media and reading materials in the format of their choice, including audio, braille, e-text and descriptive video. Would you like to find out more about the {{- name}} membership?" }, "help": { - "1": "If you'd like to learn more about {{- name}} membership - you can ask me by saying 'membership', or simply say 'stop' to exit this skill. If you have any other questions, we recommend reaching out to your local library for support. I'm listening?" + "1": "If you'd like to learn more about {{- name}} membership, you can ask me by simply saying Yes, or Stop to exit this google application. If you have any other questions, we recommend reaching out to your local library for support. I'm listening?" }, "yesOrMembership": { - "1": "Signing up is easy, you can head on over to the CELA online platform at 'URL'. Keep the name of your local library and your library or SQLA number handy, that's all you'll need. You can also ask for help at your local library. As soon as your membership is activated, you can come back to start using the {{- name}} library via Alexa, by saying 'Hey Google, launch {{- name}}'" + "1": "Signing up is easy, you can head on over to the CELA online platform at CELA Library dot c.a. Keep the name of your local library and your library or SQLA number handy, that's all you'll need. You can also ask for help at your local library. As soon as your membership is activated, you can come back to start using the {{- name}} library via Google Assistant, by saying 'Hey Google, launch Accessible reading Canada." } }, "home_user": { "enter": { "newlyUser": { "1": "Congratulations! You have succesfully linked your account and can now access all of your favorite books!", - "2": "Would you like to search for a specific book or author, get a recommendation or would you prefer starting a book from your selection ?" + "2": "Would you like to consult your bookshelf, or browse our collections? You can also search for a book by saying search followed by a book title or an author." }, "playing": { - "1": "Last time, you read Chapter {{- chapterNumber}} of {{- titleAndAuthor}}, which you can resume where you left off.", + "1": "You are listening to the {{- chapterNumber}} chapter of {{- titleAndAuthor}}, which you can pick up where you left off.", "2": "You are also reading {{- readingNumber}} other recent books, which you can choose from.", - "3": "You can search for a new one alltogether." + "3": "But there is more:" }, "regular": { - "1": "What would you like to do?" + "1": "You can consult your bookshelf, or browse our collections. You can also search for a book by saying search followed by a book title or an author.", + "2": "Resume reading. Recent books. Bookshelf. Collections. Search for a specific book: what do you want to do?" } }, "help": { - "1": "You can search for a specific book by title or author, browse our collections or check your bookshelf to start reading one of your preselected books." + "1": "You can pick the books you recently listened to with the Recent Books command. You can also check the list of books you have selected with the help of a librarian by the command Bookshelf; browse our predefined collections by the command Collections. Finally, you can search for a book by saying Search followed by a title or part of a title, an author, or both.", + "2": "What do you prefer: Resume reading. Recent books. Bookshelf. Collections or search for a book?" } }, "search": { "enter": { "1": "What book or author are you looking for ?", - "2": "In the meanwhile, is there another title or author you'd like to search for ?" + "2": "In the meanwhile, is there another title or author you'd like to search for?" }, "empty": { "1": "It seems like the book you are looking for is currently unavailable in the {{- name}} Library.", @@ -96,44 +98,46 @@ "notAvailable": "no another results available" }, "common": { - "1": "Pick one of these by saying their numbers.", - "2": "{{- symbol}}. {{- title}}", - "3": "Which one would you like to start reading?" + "1": "Pick one of these by requesting the corresponding number, or ask for the next set.", + "2": "{{- symbol}}. {{- title}}.", + "3": "Which one will you choose?" }, "empty": { "1": "Uh Oh! Nothing to read here quite yet. Not to worry though, we can fix that right away! Would you like to browse our collections? Or perhaps you'd like to search for a specific book by author or book title?" } }, "help": { - "1": "Pick one out of 3 titles by mentioning their numbers. You can also ask for 'another one'.", + "1": "At this stage, you must choose a title among the proposed set, by mentioning its number, for example number 1. You can request other titles by using the Next or Previous commands.", "2": "What would you like to do?" } }, "player": { - "start": "I start reading {{- title}}", - "askResumeLastOffset": "Do you want to pick up where it left off ?" + "explain": "Great choice! Before we start, let me remind you how this reader works. You can put your read on hold at any time by saying 'Hey Google, Pause'. 'Hey Google, Resume' will let you pick up your reading where you last left it. You can also navigate between chapters by saying 'Hey Google, next' or 'Hey Google, previous' at any time. Now, shall we get started with 'A Slow Fire Burning'?", + "start": "Let's start reading {{- title}}", + "start2": "Let's continue reading {{- title}}", + "askResumeLastOffset": "Do you want to pick up where it left off?" }, "collections": { "enter": { - "1": "Okay, would you prefer to get a book selection by theme or by genre ?" + "1": "Okay, would you prefer to get a choice of collections by theme or by genre?" }, "help": { - "1": "To hear an overview of available themes, say 'theme'. For an overview of available genres, say 'genre'. Do you want to hear a list of available themes or genres ?" + "1": "To hear an overview of available themes, say 'theme'. For an overview of available genres, say 'genre'. Do you want to hear a list of available themes or genres?" } }, - "void": "need to replace this message", + "void": "Bye!", "bye": { - "1": "Thank you for trying the app. To pick up your reading again, come back any time" + "1": "Good bye! Remember, if you need help using the Accessible Reading Canada application, our librarians are here to help. We hope you will come back soon to enjoy your favourite audio books." }, "fallback": { - "1": "I did not understand", - "2": "I really did not understand" + "1": "I did not understand, what would you like to do?", + "2": "Sorry, I really did not understand. Can you please try one more time?" }, "silence": { - "1": "I did not hear", - "2": "I really did not hear" + "1": "I did not hear anything.", + "2": "Sorry, I really don't hear well." }, "error": { "1": "Oops, something went wrong. I will send you back to the home menu" } -} \ No newline at end of file +} diff --git a/webhooks/functions/src/translation/fr/fr.json b/webhooks/functions/src/translation/fr/fr.json index 389cd69f..bf1ce36f 100644 --- a/webhooks/functions/src/translation/fr/fr.json +++ b/webhooks/functions/src/translation/fr/fr.json @@ -1,69 +1,146 @@ { - "error": { - "bearerTokenNotDefined": "Aucun identifiant défini", - "catch": "une erreur s'est produite", - "convadd": "conv.add value incorrect: {{error}}", - "urlNotValid": "url non définis ou invalide {{url}}", - "noQuery": "aucune requete demandée", - "webpubNotDefined": "webpub non définis", - "selectionListNotDefined": "selection list url non définie", - "selectionPubNotDefined": "selection url non définie", - "selectionNotAvailable": "selection non disponible" - }, "main": { - "welcome": "Bienvenue dans Valentin Audio." + "welcome": { + "noLinked": { + "1": "Bienvenue dans la bibliothèque {{- name}}, où vous pouvez accéder facilement à vos livres audios favoris. " + }, + "linked": { + "1": "Bienvenue dans votre bibliothèque {{- name}} ! Rappelez-vous, vous pouvez demander de l'aide à tout instant." + } + } + }, + "home_new_user": { + "enter": { + "first": { + "1": "Pour profiter de vos livres audio et accéder à votre liste personnelle, vous devez lier votre compte {{- name}}.", + "2": "Voulez-vous le faire maintenant ?" + } + }, + "no": { + "1": "Afin de lire des livres à l'aide de la bibliothèque {{- name}} via Google, vous devez être un membre enregistré de la bibliothèque {{- name}} et vous devez lier votre compte.", + "2": "Voulez-vous en savoir plus sur l'adhésion à {{- name}} ?" + }, + "help": { + "1": "Pour découvrir la bibliothèque {{- name}} et profiter de vos livres audio préférés via Google, vous devez connecter votre compte {{- name}}. Pour ce faire, répondez \" oui \" lorsque vous y êtes invité et suivez les instructions. Je vous enverrai alors un lien de connexion, que vous retrouverez dans l'application Google Home. Vous devrez vous connecter à votre compte {{- name}}. Vous n'aurez à le faire qu'une seule fois, et vous serez prêt à commencer à profiter du monde merveilleux des livres de {{- name}} pendant des heures !", + "2": "Voulez-vous lier votre compte maintenant ?" + }, + "maybeLater": { + "1": "Afin d'utiliser la bibliothèque {{- name}} via votre Google Home, vous devez être un membre enregistré de cette bibliothèque et lier votre compte. En attendant, vous pouvez en savoir plus sur la bibliothèque {{- name}} ou quitter l'application pour le moment.", + "2": "Que préférez-vous faire ?" + } }, - "home": { - "information": "Vous accédez à la plateforme de démonstration du projet Lis mon Livre du laboratoire européen de lecture numérique (éderlab). Le service est actuellement réservé aux testeurs de l’application. Ce texte sera à terme remplacé par des informations génériques sur la manière d’accéder à l’espace membre.", - "welcome": "Que voulez-vous faire ? Vous pouvez dire informations ou espace membres." + "home_new_user_maybe_later": { + "help": { + "1": "Vous pouvez me demander de lier votre compte, ou en apprendre plus sur la bibliothèque {{- name}}. Vous pouvez également quitter cette application en disant simplement \"Quitter\". Que décidez-vous ?" + } }, - "homeMembers": { - "welcome1": "Les commandes possibles sont: sélection, lecture, recherche. ", - "welcome2": "Que voulez-vous faire ?", - "resumeAudiobook": { - "noCurrentListening": "Aucune lecture en cours." + "home_new_user_no": { + "help": { + "1": "Afin d'utiliser la bibliothèque {{- name}} via votre Google Home, vous devez être un membre enregistré de cette bibliothèque et lier votre compte. Voulez-vous en savoir plus sur la bibliothèque {{- name}} ?" + } + }, + "info": { + "about": { + "1": "La bibliothèque {{- name}} est une organisation nationale sans but lucratif créée par les bibliothèques publiques canadiennes pour défendre le droit fondamental des Canadiens souffrant de difficultés de lecture imprimée. Ces personnes peuvent accéder à des publications numériques dans le format de leur choix, y compris l'audio, le braille, le texte électronique et la vidéo descriptive - maintenant aussi disponible via Alexa et Google Home ! Souhaitez-vous en savoir plus sur les possibilité d'inscription à la bibliothèque {{- name}} ?" }, - "selection": { - "welcome": "Les sélections disponibles sont ma liste, sélections thématiques, sélections par genre. Que voulez-vous faire ?", - "publication": "Pour choisir l'une des publications, dites son numéro.", - "next": "Pour obtenir la suite, dites suivant.", - "noNext": "Il n'y a pas de page suivante, je vais répéter la dernière page.", - "listAfterSelection": "Pour choisir une sélection, dites son numéro." + "help": { + "1": "Si vous voulez en savoir plus sur les possibilités d'adhésion à la bibliothèque {{- name}}, vous pouvez le me demander en disant simplement Oui, ou bien Quitter pour quitter cette application. Si vous avez d'autres questions, nous vous recommandons de vous adresser à votre bibliothèque locale pour obtenir de l'aide." }, - "list": { - "wrongNumber": "Le numéro {{number}} est inconnu. Veuillez choisir un autre numéro.", - "numberSelection": "J'ai trouvé {{length}} sélections.\n", - "numberPublication": "J'ai trouvé {{length}} publications.", - "pagePublication": "Vous êtes sur la page {{page}}.", - "numero": "numéro {{i}} : {{- title}}.\n", - "numeroWithAuthor": "numéro {{i}} : {{- title}} {{- author}}.\n", - "numeroWithAuthorOf": "de {{- author}}", - "noResult": "Aucun résultat trouvé.", - "repeat": "dite répéter pour recommencer" + "yesOrMembership": { + "1": "L'inscription est facile, vous pouvez vous rendre sur la plateforme en ligne de la bibliothèque {{- name}} à l'adresse biblio cahèb point c.a. Gardez à portée de main le nom de votre bibliothèque locale et votre numéro de bibliothèque ou de SQLA, c'est tout ce dont vous aurez besoin. Vous pouvez également demander de l'aide à votre bibliothèque locale. Dès que votre adhésion est activée, vous pouvez revenir pour commencer à utiliser la bibliothèque {{- name}} via Google Assistant, en disant \" Hey Google, je veux parler à Lecture Accessible Canada\"." + } + }, + "home_user": { + "enter": { + "newlyUser": { + "1": "Félicitations ! Vous avez réussi à connecter votre compte et vous pouvez maintenant accéder à tous vos livres préférés !", + "2": "Souhaitez-vous consulter votre liste personnelle, ou naviguer dans nos collections ? Vous pouvez également rechercher un livre en prononçant cherche suivi d'un titre de livre ou d'un auteur." + }, + "playing": { + "1": "Vous êtes en train d'écouter le chapitre {{- chapterNumber}} de {{- titleAndAuthor}}, que vous pouvez reprendre là où vous vous êtes arrêté.", + "2": "Vous avez également {{- readingNumber}} autres livres récents, que je peux lister.", + "3": "Mais ce n'est pas tout :" + }, + "regular": { + "1": "Vous pouvez consulter votre liste personnelle, ou naviguer dans nos collections. Vous pouvez également rechercher un livre en prononçant cherche suivi d'un titre de livre ou d'un auteur.", + "2": "Reprendre la lecture. Livres récents. Liste personnelle. Collections. Chercher un livre : que désirez-vous faire ?" + } }, - "search": "Que voulez-vous écouter ? Par exemple Zola." + "help": { + "1": "Vous pouvez consulter les livres récemment écoutés par la commande Mes livres récents. Vous pouvez également consulter la liste des livres que vous avez sélectionnés avec l'aide d'un bibliothécaire par la commande Liste personnelle, naviguer dans nos collections prédéfinies par la commande collections. Vous pouvez enfin rechercher un livre en prononçant Cherche suivi d'un titre ou d'une partie du titre, d'un auteur, ou bien les deux.", + "2": "Que préférez-vous faire : Reprendre la lecture. Livres récents. Liste personnelle. Collections ou chercher un livre ?" + } }, - "player": { - "start": "Je lance la lecture de {{- title}}", - "askResumeLastOffset": "Voulez-vous reprendre la lecture là où elle s'était arrêtée ?", - "mediaStatus": { - "notCorrect": "état de lecture incorrect." + "search": { + "enter": { + "1": "Quel titre ou auteur recherchez-vous ?", + "2": "En attendant, y a-t-il un autre titre ou auteur que vous aimeriez rechercher ?" }, - "remaining": { - "hoursAndMinute": "Il reste {{hours}} heures et {{minutes}} minutes.", - "minute": "Il reste {{minutes}} minutes." + "empty": { + "1": "Il semble que le livre que vous recherchez soit actuellement indisponible dans la bibliothèque {{- name}}.", + "2": "Vous pouvez nous suggérer des livres à ajouter à {{- website}}." + } + }, + "selection": { + "enter": { + "bookshelf": { + "first": "Voici les {{- number}} premiers titres de votre liste personnelle :", + "second": "Ou peut-être souhaitez-vous explorer les autres titres de votre liste personnelle ?" + }, + "search": "J'ai trouvé {{- number}} livres avec ce titre", + "collection": { + "publication": "J'ai trouvé {{- number}} livres", + "group": "J'ai trouvé {{- number}} groupes" + }, + "lastPage": { + "publication": "Voici les derniers livres disponibles", + "group": "Voici les derniers groupes disponibles", + "notAvailable": "aucun autre résultat disponible" + }, + "common": { + "1": "Choisissez l'un de ces titres en donnant son numéro, ou demandez les éléments suivants.", + "2": "Numéro {{- symbol}} : {{- title}}.", + "3": "Lequel choisissez-vous ?" + }, + "nextPage": { + "1": "Ou demandez la page suivante" + }, + "empty": { + "1": "En fait, il n'y a rien à lire ici pour le moment. Mais ne vous inquiétez pas, nous pouvons arranger ça tout de suite !" + } }, - "toc": { - "notFound": "Aucune table des matières disponible.", - "numero": "Choisir un numéro.", - "noNext": "Il n'y a pas de page suivante, je vais répéter la dernière page." + "help": { + "1": "A cette étape, vous devez choisir un titre parmi ceux proposés, en mentionnant son numéro, par exemple numéro 1. Vous pouvez aussi demander d'autres titres par les commandes Suivants ou Précédents.", + "2": "Que souhaitez-vous faire ?" + } + }, + "player": { + "explain": "Excellent choix ! Avant de commencer, laissez-moi vous rappeler comment fonctionne ce lecteur. Vous pouvez mettre votre lecture en attente à tout moment en disant 'Google, Pause'. 'Google, Lecture' vous permettra de reprendre votre lecture là où vous l'avez pausée. Vous pouvez également naviguer entre les chapitres en disant 'Hey Google, suivant' ou 'Hey Google, précédent' à tout moment.", + "start": "Voici donc {{- title}}", + "start2": "Reprenons la lecture de {{- title}}", + "askResumeLastOffset": "Voulez-vous reprendre la lecture là où elle a été interrompue ?" + }, + "collections": { + "enter": { + "1": "Très bien. Préférez-vous obtenir une sélection de livres par thème ou par genre ?" }, - "notAvailable": "Fonctionnalité non disponible." + "help": { + "1": "Pour entendre un aperçu des thèmes disponibles, dites thème. Pour un aperçu des genres disponibles, dites genre. Voulez-vous entendre la liste des thèmes ou des genres disponibles ?" + } + }, + "void": "au revoir!", + "bye": { + "1": "Très bien. Souvenez-vous : si vous avez besoin d'aide pour utiliser l'application Lecture Accessible Canada, nos bibliothécaires sont à votre service. Nous espérons que vous reviendrez bientôt pour profiter de vos livres audio préférés." }, - "test": { - "player": "test player {{nb}}", - "setupSdk": "setup test {{nb}}", - "webhook": "webhook work: {{- message}}" + "fallback": { + "1": "Je n'ai pas compris, que désirez-vous faire ?", + "2": "Désolé, je n'ai vraiment pas compris. Pouvez-vous tenter un dernière fois s'il vous plait ?" }, - "free": "{{- text}}" -} + "silence": { + "1": "Je n'ai pas entendu.", + "2": "Désolé, je n'entends vraiment pas bien." + }, + "error": { + "1": "Oups, quelque chose s'est mal passé. Je vous renvoie au menu d'accueil." + } +} \ No newline at end of file diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index 819dc803..2279f2e6 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.help.1" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "player.start" | "player.askResumeLastOffset" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", - "fr": "error.bearerTokenNotDefined" | "error.catch" | "error.convadd" | "error.urlNotValid" | "error.noQuery" | "error.webpubNotDefined" | "error.selectionListNotDefined" | "error.selectionPubNotDefined" | "error.selectionNotAvailable" | "main.welcome" | "home.information" | "home.welcome" | "homeMembers.welcome1" | "homeMembers.welcome2" | "homeMembers.resumeAudiobook.noCurrentListening" | "homeMembers.selection.welcome" | "homeMembers.selection.publication" | "homeMembers.selection.next" | "homeMembers.selection.noNext" | "homeMembers.selection.listAfterSelection" | "homeMembers.list.wrongNumber" | "homeMembers.list.numberSelection" | "homeMembers.list.numberPublication" | "homeMembers.list.pagePublication" | "homeMembers.list.numero" | "homeMembers.list.numeroWithAuthor" | "homeMembers.list.numeroWithAuthorOf" | "homeMembers.list.noResult" | "homeMembers.list.repeat" | "homeMembers.search" | "player.start" | "player.askResumeLastOffset" | "player.mediaStatus.notCorrect" | "player.remaining.hoursAndMinute" | "player.remaining.minute" | "player.toc.notFound" | "player.toc.numero" | "player.toc.noNext" | "player.notAvailable" | "test.player" | "test.setupSdk" | "test.webhook" | "free" + "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.enter.regular.2" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "player.explain" | "player.start" | "player.start2" | "player.askResumeLastOffset" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", + "fr": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.enter.regular.2" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "player.explain" | "player.start" | "player.start2" | "player.askResumeLastOffset" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1" }; keysWithNS: { - "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.help.1" | "en:search.enter.1" | "en:search.enter.2" | "en:search.empty.1" | "en:search.empty.2" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:player.start" | "en:player.askResumeLastOffset" | "en:collections.enter.1" | "en:collections.help.1" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", - "fr": "fr:error.bearerTokenNotDefined" | "fr:error.catch" | "fr:error.convadd" | "fr:error.urlNotValid" | "fr:error.noQuery" | "fr:error.webpubNotDefined" | "fr:error.selectionListNotDefined" | "fr:error.selectionPubNotDefined" | "fr:error.selectionNotAvailable" | "fr:main.welcome" | "fr:home.information" | "fr:home.welcome" | "fr:homeMembers.welcome1" | "fr:homeMembers.welcome2" | "fr:homeMembers.resumeAudiobook.noCurrentListening" | "fr:homeMembers.selection.welcome" | "fr:homeMembers.selection.publication" | "fr:homeMembers.selection.next" | "fr:homeMembers.selection.noNext" | "fr:homeMembers.selection.listAfterSelection" | "fr:homeMembers.list.wrongNumber" | "fr:homeMembers.list.numberSelection" | "fr:homeMembers.list.numberPublication" | "fr:homeMembers.list.pagePublication" | "fr:homeMembers.list.numero" | "fr:homeMembers.list.numeroWithAuthor" | "fr:homeMembers.list.numeroWithAuthorOf" | "fr:homeMembers.list.noResult" | "fr:homeMembers.list.repeat" | "fr:homeMembers.search" | "fr:player.start" | "fr:player.askResumeLastOffset" | "fr:player.mediaStatus.notCorrect" | "fr:player.remaining.hoursAndMinute" | "fr:player.remaining.minute" | "fr:player.toc.notFound" | "fr:player.toc.numero" | "fr:player.toc.noNext" | "fr:player.notAvailable" | "fr:test.player" | "fr:test.setupSdk" | "fr:test.webhook" | "fr:free" + "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.enter.regular.2" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:search.enter.2" | "en:search.empty.1" | "en:search.empty.2" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:player.explain" | "en:player.start" | "en:player.start2" | "en:player.askResumeLastOffset" | "en:collections.enter.1" | "en:collections.help.1" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", + "fr": "fr:main.welcome.noLinked.1" | "fr:main.welcome.linked.1" | "fr:home_new_user.enter.first.1" | "fr:home_new_user.enter.first.2" | "fr:home_new_user.no.1" | "fr:home_new_user.no.2" | "fr:home_new_user.help.1" | "fr:home_new_user.help.2" | "fr:home_new_user.maybeLater.1" | "fr:home_new_user.maybeLater.2" | "fr:home_new_user_maybe_later.help.1" | "fr:home_new_user_no.help.1" | "fr:info.about.1" | "fr:info.help.1" | "fr:info.yesOrMembership.1" | "fr:home_user.enter.newlyUser.1" | "fr:home_user.enter.newlyUser.2" | "fr:home_user.enter.playing.1" | "fr:home_user.enter.playing.2" | "fr:home_user.enter.playing.3" | "fr:home_user.enter.regular.1" | "fr:home_user.enter.regular.2" | "fr:home_user.help.1" | "fr:home_user.help.2" | "fr:search.enter.1" | "fr:search.enter.2" | "fr:search.empty.1" | "fr:search.empty.2" | "fr:selection.enter.bookshelf.first" | "fr:selection.enter.bookshelf.second" | "fr:selection.enter.search" | "fr:selection.enter.collection.publication" | "fr:selection.enter.collection.group" | "fr:selection.enter.lastPage.publication" | "fr:selection.enter.lastPage.group" | "fr:selection.enter.lastPage.notAvailable" | "fr:selection.enter.common.1" | "fr:selection.enter.common.2" | "fr:selection.enter.common.3" | "fr:selection.enter.nextPage.1" | "fr:selection.enter.empty.1" | "fr:selection.help.1" | "fr:selection.help.2" | "fr:player.explain" | "fr:player.start" | "fr:player.start2" | "fr:player.askResumeLastOffset" | "fr:collections.enter.1" | "fr:collections.help.1" | "fr:void" | "fr:bye.1" | "fr:fallback.1" | "fr:fallback.2" | "fr:silence.1" | "fr:silence.2" | "fr:error.1" }; } diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index f2216e8d..220551af 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end' | 'player__on_enter' | 'player__intent__media_status_finished' | 'player__intent__media_status_paused' | 'player__intent__media_status_stopped' | 'player__intent__media_status_failed' | 'search__on_enter' | 'search__intent__search_query' | 'search__intent__search' | 'collections__on_enter' | 'collections__intent__bookshelf' | 'collections__intent__by_genre' | 'collections__intent__by_theme' | 'collections__intent__help' | 'collections__intent__fallback' | 'collections__intent__fallback_end' | 'collections__intent__silence' | 'collections__intent__silence_end' | 'player_prequel__on_enter' | 'player_prequel__intent__yes' | 'player_prequel__intent__no'; +export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end' | 'player__on_enter' | 'player__intent__media_status_finished' | 'player__intent__media_status_paused' | 'player__intent__media_status_stopped' | 'player__intent__media_status_failed' | 'search__on_enter' | 'search__intent__search_query' | 'search__intent__search' | 'collections__on_enter' | 'collections__intent__bookshelf' | 'collections__intent__by_genre' | 'collections__intent__by_theme' | 'collections__intent__help' | 'collections__intent__fallback' | 'collections__intent__fallback_end' | 'collections__intent__silence' | 'collections__intent__silence_end' | 'player_prequel__on_enter' | 'player_prequel__intent__yes' | 'player_prequel__intent__no' | 'home_user__intent__recent_books' | 'info__intent__no'; diff --git a/webhooks/functions/tsconfig.json b/webhooks/functions/tsconfig.json index 5cb7356c..95c910cc 100644 --- a/webhooks/functions/tsconfig.json +++ b/webhooks/functions/tsconfig.json @@ -10,7 +10,8 @@ "outDir": "build", "experimentalDecorators": true, "strictNullChecks": true, - "resolveJsonModule": true + "resolveJsonModule": true, + "downlevelIteration": true }, "include": [ "src/**/*" From f2f610b8ebf911db5fb761f1839b66431d476930 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Mon, 4 Apr 2022 14:20:55 +0200 Subject: [PATCH 162/180] cela-dev to devmerge to dev2 to develop (PR #74) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update functions.yml * Update functions.yml * Update functions.yml * sdk test prod * test save service * Revert "selection menu lvl3" This reverts commit 5d234c577cf09f8cae208a03b8b7b37d57896041. * follow previous reverse commit * follow previous commit : remove unused file * fix: test sdk prod replace home_lvl1 * Update README.md * actions update * fix: test * Migration DEVELOP to MAIN (PR #16) * setup wehooks * fix project-id in actions * push github actions test sdk DEV * github action test sdk dev on PR too * webhooks: setup_test_sdk * fix webhooks setup test sdk * test/dev: test-1 home+setup * webhooks fix test player * fix reprendre la lecture sentence * some first search and player test on develop * test: selections * webhooks: switch to typescript * webhooks: type user params * strict null checks (PR #7) * eslint * improve user-storage (PR #6) * typing sdk scene * chore update firebase functions * fix deploy dev * clean * finite state machine (PR #8) * fix test-webhook * Selection List (PR #9) * fix: storageDto * fix: selection * fix: reset user storage at the end * test: test update * fix: firestore timestamp format * fix: test and lint * fix: firestore timestamp object conversion * fix: test * i18n | constant values (PR #10) * fix: translation wrongNumber * fix: lint * fix: github actions deploy and test jobs * fix: github actions deploy * feature: stop in selections * fix: stop in selection_list * I18n (PR #12) * fix: i18n' * fix: i18n * fix: constant * fix: translation * fix: i18n escaping * fix i18n * locale (PR #14) * player (PR #13) * next intent in select_publication scene (PR #15) * fix: next feature * fix: next feature with Laurent * lint * fix: next feature * lint * fix: listPublications * fix: menu intent in select_group * test * Update sdk-test-dev.yml * fix: test * fix: selection * fix: j'ai trouvé * fix some minor evolution * my list redirected from home_member * feature: lance la lecture * fix: media status stop * fix: sdk dev * fix: media-status stopped * sdk * fix github actions deploy function * set prod mode in the webhook * fix: test1 * cela first commit * rm unused file * sdk prod pull * merge sdk prod to cela-prod * update: fr.json main.welcome * [skip-ci] deploy actions * chore cela-dev * chore github actions * chore: pull latest sdk * fix: pronunciation dev * cela-2 branding * rm old cela-2 cela-dev files * Update README.md * push and then pull gactions sdk * replace edrlab-1 with cela-2 * fix: remove to set NO_LINKED to authenticationState when no storageModel avalaible no bearer token * github actions: add function deploy for cela-dev * set CELA API URLs * fix: add authentication credentials to edrlab cloud function * update gitignore firebase . nyc * fix: NAME * fix test: replace edrlab with cela * i18n: french translation * sdk: settings EN and FR * README * sdk: french intents * sdk: fix type in search and select book intent * fix: locale * sdk: search french intent * fix: alexa to google assistant keyword * sdk: recommandations in collections intent: * fix: home_user scene on-enter split SESSION AND REPEAT AND TEST IF NEWLY LINKED OR PLAYING * fix: home_user intent help and regular user state * fix: locale in app catch Assistant * fix: add a point in selection list i18n * sdk: bookshelf and search intents * feature: recent_books intent * fix: player_prequel * test: fix previous commit * fix: peer review with @Laurent * fixes #44 : CELA NAME in en/fr * fixes #46 selection - select_books intent twice access to on_enter on assistant looping -> because on_enter must say something to the user In this case STATE=RUNNING and repeat twice selection list One in select_books and one in on_enter I'm disabling the loop in Assistant handle when STATE=RUNNING * fix: home_user playing test * fix: persist media player on cancel and fallback3 and silence3 * fix: handle bad fetcher request with a stub opdsFeed - no publications * feature: add a timeout on app.handle * fix infinite loop in gactions platform beetwen selection and search search query is keep across session need to force user to repeat it * fix: search on enter should say somthing * fix: double the timer 4s to 8s @todo see in real life the impact * Update of the French and English dialogs * fixes #53 fixes #49: infinite loop on empty search * fixes #53 fixes #49: infinite loop on empty search * fixes #55: info.about.1 twice said * fixes #51: home_user new_playing missing a translation * fixes #38: void * sdk: send prompt disalbled for en/fr -> fail submissiong * sdk: bookshelf and recent_books fr * pull from gactions * add test on en translation * fix info yes or membership en * New dialog enhancements, mainly english * Tidy up the list of titles / collections message * translation review with unitary tests * fix test previous commit * fix: info intent info__intent__no * sdk: select book intent * sdk: by genre * fix PR #61 update translations * fix: surround webpub request with a try catch set eror code 401 to WebpubError extends from Error and catch it on app.catch and say specific message to user then quit * follow previous commit * Update functions-edrlab-dev.yml * sdk: improve english intent * sdk: recent_book * sdk: recent_book * PR #68: update dialog add ssml @llemeurfr * fix: ssml speak typo * fix: ssml regular expression * fix: test * fix: update opds-fetcher to set a simple locale * fixes #50: current book vs recent books * follow previous commit: add 2 untrack files : current book intent * fix #52: set the right handler from scene to search * fixes #45: next page condition on selection scene * fix #42: cache http * sdk: search en * fix pr #71: @llemeurfr * merge to develop * cela to edrlab name Co-authored-by: Laurent Le Meur --- sdk/custom/intents/current_book.yaml | 8 +++ sdk/custom/intents/en/bookshelf.yaml | 5 ++ sdk/custom/intents/en/current_book.yaml | 5 ++ sdk/custom/intents/en/recent_books.yaml | 5 +- sdk/custom/intents/en/repeat.yaml | 1 + sdk/custom/intents/en/search.yaml | 6 ++ sdk/custom/intents/recent_books.yaml | 5 -- sdk/custom/scenes/home_user.yaml | 3 + sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 1 + webhooks/functions/package-lock.json | 68 +++++++++++-------- webhooks/functions/package.json | 2 +- webhooks/functions/src/constants.ts | 15 ++-- .../functions/src/controller/Assistant.ts | 2 +- webhooks/functions/src/controller/Machine.ts | 19 ++++-- .../src/controller/handler/home_user.ts | 14 ++++ .../src/controller/handler/selection.ts | 16 +++-- .../functions/src/sdk/collections.test.ts | 2 +- .../src/sdk/home_new_user_no.test.ts | 2 +- webhooks/functions/src/sdk/home_user.test.ts | 50 +++++++++++--- webhooks/functions/src/sdk/info.test.ts | 2 +- webhooks/functions/src/sdk/selection.test.ts | 35 +++++----- webhooks/functions/src/tools.ts | 16 +++++ webhooks/functions/src/translation/en/en.json | 51 +++++++------- webhooks/functions/src/translation/fr/fr.json | 54 ++++++++------- webhooks/functions/src/typings/i18n.d.ts | 8 +-- .../functions/src/typings/sdkHandler.d.ts | 2 +- 26 files changed, 261 insertions(+), 136 deletions(-) create mode 100644 sdk/custom/intents/current_book.yaml create mode 100644 sdk/custom/intents/en/current_book.yaml create mode 100644 webhooks/functions/src/tools.ts diff --git a/sdk/custom/intents/current_book.yaml b/sdk/custom/intents/current_book.yaml new file mode 100644 index 00000000..b723aa6f --- /dev/null +++ b/sdk/custom/intents/current_book.yaml @@ -0,0 +1,8 @@ +trainingPhrases: +- Reprendre ma lecture +- Reprends ma lecture +- Reprends +- Reprends le dernier livre +- Reprends la lecture +- Reprendre la lecture +- Reprendre diff --git a/sdk/custom/intents/en/bookshelf.yaml b/sdk/custom/intents/en/bookshelf.yaml index e9efd62b..a627ab60 100644 --- a/sdk/custom/intents/en/bookshelf.yaml +++ b/sdk/custom/intents/en/bookshelf.yaml @@ -1,2 +1,7 @@ trainingPhrases: +- personal list +- browse my bookshelf +- book shelves +- book shelf +- my bookshelf - bookshelf diff --git a/sdk/custom/intents/en/current_book.yaml b/sdk/custom/intents/en/current_book.yaml new file mode 100644 index 00000000..7b2bf448 --- /dev/null +++ b/sdk/custom/intents/en/current_book.yaml @@ -0,0 +1,5 @@ +trainingPhrases: +- Resume +- Resume reading +- Resume playback +- resume the last book diff --git a/sdk/custom/intents/en/recent_books.yaml b/sdk/custom/intents/en/recent_books.yaml index 23703a23..1d5c775c 100644 --- a/sdk/custom/intents/en/recent_books.yaml +++ b/sdk/custom/intents/en/recent_books.yaml @@ -1,3 +1,6 @@ trainingPhrases: -- resume playings +- last book +- play the last book +- last books +- recent - recent books diff --git a/sdk/custom/intents/en/repeat.yaml b/sdk/custom/intents/en/repeat.yaml index 7f375617..4818ec7e 100644 --- a/sdk/custom/intents/en/repeat.yaml +++ b/sdk/custom/intents/en/repeat.yaml @@ -1,3 +1,4 @@ trainingPhrases: +- again - repeat - i do not understand diff --git a/sdk/custom/intents/en/search.yaml b/sdk/custom/intents/en/search.yaml index 41504ffa..1469f390 100644 --- a/sdk/custom/intents/en/search.yaml +++ b/sdk/custom/intents/en/search.yaml @@ -1,4 +1,10 @@ trainingPhrases: +- search for a book +- search for a book by ($query 'Ernest Hemingway' auto=false) +- I want to search for a book +- search for a specific book +- I am looking for ($query 'The Little Prince by Antoine de Saint-Exupéry' auto=false) +- search - find - search for - I am looking for a book ($query 'The Little Prince by Antoine de Saint-Exupéry' diff --git a/sdk/custom/intents/recent_books.yaml b/sdk/custom/intents/recent_books.yaml index 2bf7418c..54fed1ac 100644 --- a/sdk/custom/intents/recent_books.yaml +++ b/sdk/custom/intents/recent_books.yaml @@ -1,12 +1,7 @@ trainingPhrases: - mes livres récents -- reprends -- reprendre ma lecture -- reprendre la lecture - derniers livres - livres récents - voir mes derniers livres - voir mes livres récents -- reprendre ma lecture -- reprendre la lecture - derniers livres lus diff --git a/sdk/custom/scenes/home_user.yaml b/sdk/custom/scenes/home_user.yaml index 4395e757..2e143efd 100644 --- a/sdk/custom/scenes/home_user.yaml +++ b/sdk/custom/scenes/home_user.yaml @@ -17,6 +17,9 @@ intentEvents: - handler: webhookHandler: home_user__intent__recent_books intent: recent_books +- handler: + webhookHandler: home_user__intent__current_book + intent: current_book - handler: webhookHandler: home_user__intent__fallback intent: actions.intent.NO_MATCH_1 diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index 85df2d22..939e1268 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -85,6 +85,7 @@ handlers: - name: player_prequel__intent__no - name: home_user__intent__recent_books - name: info__intent__no +- name: home_user__intent__current_book httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/package-lock.json b/webhooks/functions/package-lock.json index 75d3aa25..fe3b4d44 100644 --- a/webhooks/functions/package-lock.json +++ b/webhooks/functions/package-lock.json @@ -3671,14 +3671,22 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true }, "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "requires": { - "minimist": "^1.2.5" + "minimist": "^1.2.6" + }, + "dependencies": { + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + } } }, "mocha": { @@ -3786,9 +3794,9 @@ } }, "nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==" + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.2.tgz", + "integrity": "sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==" }, "natural-compare": { "version": "1.4.0", @@ -4078,15 +4086,15 @@ } }, "opds-fetcher-parser": { - "version": "git+https://github.com/edrlab/opds_fetcher_parser.git#f74c1bfbaccc7508de2445bb16aacc8bd6ad9641", - "from": "git+https://github.com/edrlab/opds_fetcher_parser.git#f74c1bfbaccc7508de2445bb16aacc8bd6ad9641", + "version": "git+https://github.com/edrlab/opds_fetcher_parser.git#be1b96f67499102675676b03a5aee4d267924972", + "from": "git+https://github.com/edrlab/opds_fetcher_parser.git#be1b96f67499102675676b03a5aee4d267924972", "requires": { "moment": "^2.29.1", "nanoid": "^3.1.23", "r2-lcp-js": "^1.0.30", "r2-opds-js": "^1.0.35", "r2-shared-js": "^1.0.51", - "ts-fetch": "github:edrlab/ts_fetch#bc8166db8813b791a212f521ef79a74f0ea5b175" + "ts-fetch": "github:edrlab/ts_fetch#bdb3444e608e6ae894a01cd703805e06ec991d66" } }, "optionator": { @@ -4434,9 +4442,9 @@ }, "dependencies": { "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } @@ -4458,9 +4466,9 @@ }, "dependencies": { "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } @@ -4468,16 +4476,16 @@ } }, "r2-shared-js": { - "version": "1.0.56", - "resolved": "https://registry.npmjs.org/r2-shared-js/-/r2-shared-js-1.0.56.tgz", - "integrity": "sha512-HLhrCjn7/nL44mqf6rtSiguddXBMiXpr02z14wlNy28EMyxFG8ir7iZYYwVmZ6h+BOVgTYvml+4u8rqHsJNRrg==", + "version": "1.0.59", + "resolved": "https://registry.npmjs.org/r2-shared-js/-/r2-shared-js-1.0.59.tgz", + "integrity": "sha512-hcSc9a00zWaETKSRcDk8qhAT9zUXfVGgnD1g+BLS/bMvUnl7wkn3JdowXGwMyYS1bb985tCSIwzq215LRhYhzQ==", "requires": { "@xmldom/xmldom": "^0.8.1", - "debug": "^4.3.3", + "debug": "^4.3.4", "fast-deep-equal": "^3.1.3", "he": "^1.2.0", "image-size": "^1.0.1", - "mime-types": "^2.1.34", + "mime-types": "^2.1.35", "moment": "^2.29.1", "r2-lcp-js": "^1.0.35", "r2-utils-js": "^1.0.31", @@ -4489,9 +4497,9 @@ }, "dependencies": { "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } @@ -4531,9 +4539,9 @@ }, "dependencies": { "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } @@ -5105,8 +5113,8 @@ "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=" }, "ts-fetch": { - "version": "github:edrlab/ts_fetch#bc8166db8813b791a212f521ef79a74f0ea5b175", - "from": "github:edrlab/ts_fetch#bc8166db8813b791a212f521ef79a74f0ea5b175", + "version": "github:edrlab/ts_fetch#bdb3444e608e6ae894a01cd703805e06ec991d66", + "from": "github:edrlab/ts_fetch#bdb3444e608e6ae894a01cd703805e06ec991d66", "requires": { "fetch-cookie": "^1.0.0", "node-fetch": "^2.6.7", diff --git a/webhooks/functions/package.json b/webhooks/functions/package.json index 8568d1db..1ac1996a 100644 --- a/webhooks/functions/package.json +++ b/webhooks/functions/package.json @@ -28,7 +28,7 @@ "firebase-admin": "^9.8.0", "firebase-functions": "^3.16.0", "i18next": "^21.5.3", - "opds-fetcher-parser": "git+https://github.com/edrlab/opds_fetcher_parser.git#f74c1bfbaccc7508de2445bb16aacc8bd6ad9641", + "opds-fetcher-parser": "git+https://github.com/edrlab/opds_fetcher_parser.git#be1b96f67499102675676b03a5aee4d267924972", "reflect-metadata": "^0.1.13", "validator": "^13.7.0" }, diff --git a/webhooks/functions/src/constants.ts b/webhooks/functions/src/constants.ts index 8e5d297e..0baf83ea 100644 --- a/webhooks/functions/src/constants.ts +++ b/webhooks/functions/src/constants.ts @@ -1,11 +1,12 @@ -export const NAME = "EDRLAB"; -export const setName = (locale: TLang) => {}; +export let NAME = ""; +export const NAME_EN = "EDRLAB"; +export const NAME_FR = "EDRLAB"; +export const setName = (lang: TLang) => NAME = lang === 'fr' ? NAME_FR : NAME_EN; export const API_BASE_URL = "https://storage.googleapis.com/audiobook_edrlab/feed.json"; -export const EDRLAB_FUNCTION_URL = 'https://us-central1-edrlab-1.cloudfunctions.net/manifest'; - -export const ALL_PUBLICATION_LIST_URL = "https://storage.googleapis.com/audiobook_edrlab/navigation/all.json"; +export const EDRLAB_FUNCTION_URL = "https://storage.googleapis.com/audiobook_edrlab/feed.json"; +// export const ALL_PUBLICATION_LIST_URL = "https://storage.googleapis.com/audiobook_edrlab/navigation/all.json"; export const BOOKSHELF_URL = 'https://storage.googleapis.com/audiobook_edrlab/groups/popular.json'; export const SEARCH_URL = 'https://europe-west1-audiobooks-a6348.cloudfunctions.net/indexer?url=https://storage.googleapis.com/audiobook_edrlab/navigation/all.json&query={query}'; export const SEARCH_URL_FN = (value: string) => SEARCH_URL.replace("{query}", value); @@ -24,3 +25,7 @@ export const PROJECT_ID = 'edrlab-1'; export const TIMER = 8000; export type TLang = 'fr' | 'en'; + + +// init +setName(DEFAULT_LANGUAGE); diff --git a/webhooks/functions/src/controller/Assistant.ts b/webhooks/functions/src/controller/Assistant.ts index 8b2b5d7f..d2c0b249 100644 --- a/webhooks/functions/src/controller/Assistant.ts +++ b/webhooks/functions/src/controller/Assistant.ts @@ -42,7 +42,7 @@ export class Assistant { console.log('WEBPUB ERROR code 401'); if (this._locale === 'en') { - conv.add('Sorry, it is not possible to go further. Please unlink your CELA account from your assistant, then link them again.'); + conv.add('Sorry, it is not possible to go further. Please unlink your EDRLAB account from your assistant, then link them again.'); } else if (this._locale === 'fr') { conv.add('Désolé, impossible d\'aller plus loin : dissociez votre compte CAÉB de votre assistant puis ré-associez les.'); } diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 2eaf0bb5..0388f6b8 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -12,6 +12,8 @@ import {MediaType, OptionalMediaControl} from '@assistant/conversation/dist/api/ import {IOpdsLinkView, IOpdsPublicationView, IOpdsResultView} from 'opds-fetcher-parser/build/src/interface/opds'; import {TSdkHandler} from '../typings/sdkHandler'; import {WebpubError} from '../error'; +import {stall} from '../tools'; +import {IWebPubView} from 'opds-fetcher-parser/build/src/interface/webpub'; export class Machine { private _conv: IConversationV3; @@ -85,6 +87,9 @@ export class Machine { } if (this._sayAcc) { + if (/.*<.*>.*<\/.*>.*/.test(this._sayAcc)) { + this._sayAcc = '' + this._sayAcc + ''; + } console.info('SAY: ', this._sayAcc); this._conv.add(this._sayAcc); } @@ -215,6 +220,12 @@ export class Machine { public isCurrentlyPlaying() { const {url, time, index} = this.playerCurrent; + // if (!playing) { + // return false; // @TODO: need to define the use of this boolean + // } + if (url === undefined || time === undefined || index === undefined) { + return false; + } if (!this.isValidHttpUrl(url)) { throw new Error('not valid playing url'); } @@ -556,7 +567,7 @@ export class Machine { ); } - private async webpubRequest(url: string) { + private webpubRequest: (url: string) => Promise = stall(async (url: string) => { if (!validator.isURL(url)) { throw new Error('url not valid : ' + url); } @@ -571,9 +582,9 @@ export class Machine { error.code = 401; throw error; } - } + }); - private async feedRequest(url: string) { + private feedRequest: (url: string) => Promise = stall(async (url: string) => { if (!this._fetcher) { throw new Error('no fetcher available !'); } @@ -622,7 +633,7 @@ export class Machine { console.error('FETCHER ERROR END'); } return feed; - } + }); private removeSessionDataWhenNewUserSession() { if (!this._model) { diff --git a/webhooks/functions/src/controller/handler/home_user.ts b/webhooks/functions/src/controller/handler/home_user.ts index 200959af..e11d727b 100644 --- a/webhooks/functions/src/controller/handler/home_user.ts +++ b/webhooks/functions/src/controller/handler/home_user.ts @@ -16,6 +16,7 @@ export const home_user = (app: Assistant) => { app.handle("home_user__intent__silence", help); app.handle("home_user__intent__silence_end", missing); app.handle("home_user__intent__recent_books", recentBooks); + app.handle("home_user__intent__current_book", currentBook); } @@ -109,6 +110,19 @@ const recentBooks: THandlerFn = (m) => { }) } +const currentBook: THandlerFn = (m) => { + + const isPlaying = m.isCurrentlyPlaying(); + if (isPlaying) { + + m.nextScene = 'player_prequel'; + } else { + + m.say('home_user.currentBook.1'); + m.nextScene = 'home_user'; + } +} + const help: THandlerFn = (m) => { m.setSessionState("home_user", "REPEAT"); diff --git a/webhooks/functions/src/controller/handler/selection.ts b/webhooks/functions/src/controller/handler/selection.ts index 73d4a96b..f0ac9f3c 100644 --- a/webhooks/functions/src/controller/handler/selection.ts +++ b/webhooks/functions/src/controller/handler/selection.ts @@ -48,24 +48,23 @@ export const enter: THandlerFn = async (m) => { // redirect to nextScene 'selection' for group // or 'player-prequel' for a publication + const nextLink = kind === "GROUP" ? await m.getNexLinkGroupWithUrl(url) : await m.getNexLinkPublicationWithUrl(url); + const nextPageBool = !!nextLink; if (m.selectionSession.nextUrlCounter) { - const nextLink = kind === "GROUP" ? await m.getNexLinkGroupWithUrl(url) : await m.getNexLinkPublicationWithUrl(url); - if (nextLink) { - - } else { + if (!nextLink) { if (kind === "GROUP") { m.say("selection.enter.lastPage.group"); } else { m.say("selection.enter.lastPage.publication"); } } - } else { + // intro if (handler === "home_user__intent__bookshelf") { const {publication} = await m.getPublicationFromFeed(url); // @TODO fix it .. twice call to api m.say('selection.enter.bookshelf.first', {number: publication.length}); - } else if (handler === "home_user__intent__search") { + } else if (handler === "search__on_enter") { const {length} = await m.getPublicationFromFeed(url); // @TODO fix it .. twice call to api m.say('selection.enter.search', {number: length}); } @@ -74,7 +73,10 @@ export const enter: THandlerFn = async (m) => { // @TODO handle collection group or publication // list groups or publication - m.say('selection.enter.common.1', {pageSuivante: ''}); + m.say('selection.enter.common.1'); + if (nextPageBool) { + m.say('selection.enter.nextPage.1'); + } const list = kind === "GROUP" ? (await m.getGroupsFromFeed(url)).groups.map(({title}) => title) : (await m.getPublicationFromFeed(url)).publication.map(({title}) => title); diff --git a/webhooks/functions/src/sdk/collections.test.ts b/webhooks/functions/src/sdk/collections.test.ts index 12ffbdf9..ec15252e 100644 --- a/webhooks/functions/src/sdk/collections.test.ts +++ b/webhooks/functions/src/sdk/collections.test.ts @@ -121,7 +121,7 @@ describe(scene + ' handler', () => { data.scene.next.name.should.to.be.eq('selection'); }); - const help = `To hear an overview of available themes, say 'theme'. For an overview of available genres, say 'genre'. Do you want to hear a list of available themes or genres?\n`; + const help = `To hear an overview of available themes, say 'by theme'. For an overview of available genres, say 'by genre'.\n`; it('help', async () => { body.handler.name = 'collections__intent__help'; diff --git a/webhooks/functions/src/sdk/home_new_user_no.test.ts b/webhooks/functions/src/sdk/home_new_user_no.test.ts index d114b137..b6628c93 100644 --- a/webhooks/functions/src/sdk/home_new_user_no.test.ts +++ b/webhooks/functions/src/sdk/home_new_user_no.test.ts @@ -92,7 +92,7 @@ describe(scene + ' handler', () => { data.scene.next.name.should.to.be.eq('home_new_user_no'); }); - const help = `In order to use the EDRLAB library via your Google Home, you must be a registered member of the library and link your account. Would you like to learn more about the EDRLAB Livrary?\n`; + const help = `In order to use the EDRLAB library via your Google Home, you must be a registered member of the library and link your account. Would you like to learn more about the EDRLAB Library?\n`; it('help', async () => { body.handler.name = 'home_new_user_no__intent__help'; diff --git a/webhooks/functions/src/sdk/home_user.test.ts b/webhooks/functions/src/sdk/home_user.test.ts index 200b14ee..378e9c90 100644 --- a/webhooks/functions/src/sdk/home_user.test.ts +++ b/webhooks/functions/src/sdk/home_user.test.ts @@ -30,6 +30,9 @@ const yaml = `intentEvents: - handler: webhookHandler: home_user__intent__recent_books intent: recent_books +- handler: + webhookHandler: home_user__intent__current_book + intent: current_book - handler: webhookHandler: home_user__intent__fallback intent: actions.intent.NO_MATCH_1 @@ -67,7 +70,7 @@ describe('home_user handler', () => { body.scene.name = scene; body.session.id = 'on enter'; // new session - const message = 'Would you like to consult your bookshelf, or browse our collections? You can also search for a book by saying search followed by a book title or an author.\n'; + const message = 'Would you like to consult your bookshelf, or browse our collections? You can also search for a book by saying search for. Followed by a book title or an author.\n'; const data = await expressMocked(body, headers); data.prompt.firstSimple.speech.should.to.be.eq(message); @@ -77,7 +80,7 @@ describe('home_user handler', () => { body.scene.name = scene; body.session.id = 'id'; // new session - const message = 'Would you like to consult your bookshelf, or browse our collections? You can also search for a book by saying search followed by a book title or an author.\n'; + const message = 'Would you like to consult your bookshelf, or browse our collections? You can also search for a book by saying search for. Followed by a book title or an author.\n'; const pullData = parsedDataClone(); const model = await storageModelMocked(pullData); @@ -90,7 +93,7 @@ describe('home_user handler', () => { body.scene.name = scene; body.session.id = 'on enter with session state but new session undefined so the session data is not removed'; // new session - const message = 'Would you like to consult your bookshelf, or browse our collections? You can also search for a book by saying search followed by a book title or an author.\n'; + const message = 'Would you like to consult your bookshelf, or browse our collections? You can also search for a book by saying search for. Followed by a book title or an author.\n'; const pullData = parsedDataClone(); const model = await storageModelMocked(pullData); @@ -103,7 +106,7 @@ describe('home_user handler', () => { body.scene.name = scene; body.session.id = 'test'; - const message = 'Would you like to consult your bookshelf, or browse our collections? You can also search for a book by saying search followed by a book title or an author.\n'; + const message = 'Would you like to consult your bookshelf, or browse our collections? You can also search for a book by saying search for. Followed by a book title or an author.\n'; const pullData = parsedDataClone(); const model = await storageModelMocked(pullData); @@ -134,8 +137,8 @@ describe('home_user handler', () => { const data = await expressMocked(body, headers, pullData, undefined, webpub); console.log(JSON.stringify(data, null, 4)); - data.prompt.firstSimple.speech.should.to.be.eq('You are listening to the 10 chapter of my title, hello, which you can pick up where you left off.\n' + - 'But there is more:\n' + + data.prompt.firstSimple.speech.should.to.be.eq('You are listening to the 10 chapter of my title, hello, which you can now pick up.\n' + + 'And, of course, \n' + 'You can consult your bookshelf, or browse our collections. You can also search for a book by saying search followed by a book title or an author.\n' + 'Resume reading. Recent books. Bookshelf. Collections. Search for a specific book: what do you want to do?\n'); }); @@ -173,9 +176,9 @@ describe('home_user handler', () => { const data = await expressMocked(body, headers, pullData, undefined, webpub); console.log(JSON.stringify(data, null, 4)); - data.prompt.firstSimple.speech.should.to.be.eq('You are listening to the 10 chapter of my title, hello, which you can pick up where you left off.\n' + + data.prompt.firstSimple.speech.should.to.be.eq('You are listening to the 10 chapter of my title, hello, which you can now pick up.\n' + 'You are also reading 3 other recent books, which you can choose from.\n' + - 'But there is more:\n' + + 'And, of course, \n' + 'You can consult your bookshelf, or browse our collections. You can also search for a book by saying search followed by a book title or an author.\n' + 'Resume reading. Recent books. Bookshelf. Collections. Search for a specific book: what do you want to do?\n'); }); @@ -234,7 +237,7 @@ describe('home_user handler', () => { pullData.player.current.index = 9; pullData.player.current.url = 'https://my.url'; pullData.player.current.time = 0; - pullData.player.current.playing = true; + pullData.player.current.playing = false; pullData.player.history = { // @ts-ignore @@ -265,6 +268,35 @@ describe('home_user handler', () => { model.data.store.session.scene.selection.state.should.to.be.eq('RUNNING'); }); + it('current book available', async () => { + body.handler.name = 'home_user__intent__current_book'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + pullData.player.current.index = 9; + pullData.player.current.url = 'https://my.url'; + pullData.player.current.time = 0; + pullData.player.current.playing = false; + + const model = await storageModelMocked(pullData); + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + + data.scene.next.name.should.to.be.eq('player_prequel'); + }); + + it('current book not available', async () => { + body.handler.name = 'home_user__intent__current_book'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + + const model = await storageModelMocked(pullData); + const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); + + data.scene.next.name.should.to.be.eq('home_user'); + data.prompt.firstSimple.speech.should.to.be.eq('Uh Oh! Nothing to read here quite yet.\n'); + }); + it('browse collections', async () => { body.handler.name = 'home_user__intent__collections'; body.scene.name = scene; diff --git a/webhooks/functions/src/sdk/info.test.ts b/webhooks/functions/src/sdk/info.test.ts index 84fbe4a4..60e28abf 100644 --- a/webhooks/functions/src/sdk/info.test.ts +++ b/webhooks/functions/src/sdk/info.test.ts @@ -74,7 +74,7 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers); - const message = `Signing up is easy, you can head on over to the CELA online platform at CELA Library dot c.a. Keep the name of your local library and your library or SQLA number handy, that's all you'll need. You can also ask for help at your local library. As soon as your membership is activated, you can come back to start using the EDRLAB library via Google Assistant, by saying 'Hey Google, launch Accessible reading Canada.\n`; + const message = `Signing up is easy, you can head on over to the EDRLAB online platform at celalibrary dot ca. Keep the name of your local library and your library or SQLA number handy, that's all you'll need. You can also ask for help at your local library. As soon as your membership is activated, you can come back to start using the EDRLAB library via Google Assistant, by saying Hey Google, launch Accessible reading Canada.\n`; data.prompt.firstSimple.speech.should.to.be.eq(message); data.scene.next.name.should.to.be.eq('actions.scene.END_CONVERSATION'); diff --git a/webhooks/functions/src/sdk/selection.test.ts b/webhooks/functions/src/sdk/selection.test.ts index 0e6fd656..8c75d3c4 100644 --- a/webhooks/functions/src/sdk/selection.test.ts +++ b/webhooks/functions/src/sdk/selection.test.ts @@ -54,10 +54,10 @@ describe(scene + ' handler', () => { }); }); - const messageHelpers = (number: number, it: Array<[nb: number, title: string]>) => { - const a = 'Pick one of these by requesting the corresponding number, or ask for the next set.\n'; + const messageHelpers = (number: number, it: Array<[nb: number, title: string]>, nextPage = false) => { + const a = 'Pick one of these by requesting the corresponding number.\n' + (nextPage ? 'Or ask for the next set.\n' : ''); const b = it.reduce((pv, [nb, title]) => pv + `${nb}. ${title}\n`, ''); - const c = 'Which one will you choose?\n'; + const c = 'Which number do you choose?\n'; return a + b + c; }; @@ -190,7 +190,7 @@ describe(scene + ' handler', () => { }, }); - const testStateRunningPublication = () => { + const testStateRunningPublication = (n = false) => { const pullData = parsedDataClone(); pullData.session.scene.selection.state = 'RUNNING'; pullData.session.scene.selection.url = 'http://my.url'; @@ -237,11 +237,14 @@ describe(scene + ' handler', () => { [1, 'first publication.'], [2, 'second publication.'], [3, 'third publication.'], - ]); + ], n); + + console.log(message); + return {pullData, feed, message}; }; - const testStateRunningGroup = () => { + const testStateRunningGroup = (n = false) => { const pullData = parsedDataClone(); pullData.session.scene.selection.state = 'RUNNING'; pullData.session.scene.selection.url = 'http://my.url'; @@ -273,7 +276,7 @@ describe(scene + ' handler', () => { [1, 'first group.'], [2, 'second group.'], [3, 'third group.'], - ]); + ], n); return {pullData, feed, message}; }; @@ -375,7 +378,7 @@ describe(scene + ' handler', () => { feed.links = {}; const data = await expressMocked(body, headers, pullData, feed); - data.prompt.firstSimple.speech.should.to.be.eq('Here\'s the last available books\n' + message); + data.prompt.firstSimple.speech.should.to.be.eq('Here\'s the last available books.\n' + message); // data.scene.next.name.should.to.be.eq('selection'); }); @@ -390,7 +393,7 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers, pullData, feed); // must say the first page - data.prompt.firstSimple.speech.should.to.be.eq('Here\'s the last available groups\n' + message); + data.prompt.firstSimple.speech.should.to.be.eq('Here\'s the last available groups.\n' + message); // data.scene.next.name.should.to.be.eq('selection'); }); @@ -398,7 +401,7 @@ describe(scene + ' handler', () => { body.handler.name = 'selection__on_enter'; body.scene.name = scene; - const {pullData, feed, message} = testStateRunningPublication(); + const {pullData, feed, message} = testStateRunningPublication(true); pullData.session.scene.selection.nextUrlCounter = 3; // @ts-ignore feed.links = { @@ -418,7 +421,7 @@ describe(scene + ' handler', () => { body.handler.name = 'selection__on_enter'; body.scene.name = scene; - const {pullData, feed, message} = testStateRunningGroup(); + const {pullData, feed, message} = testStateRunningGroup(true); pullData.session.scene.selection.nextUrlCounter = 3; // @ts-ignore feed.links = { @@ -439,7 +442,7 @@ describe(scene + ' handler', () => { body.handler.name = 'selection__on_enter'; body.scene.name = scene; - const {pullData, feed, message} = testStateRunningPublication(); + const {pullData, feed, message} = testStateRunningPublication(true); pullData.session.scene.selection.nextUrlCounter = 0; pullData.session.scene.selection.from = 'home_user__intent__bookshelf'; // @ts-ignore @@ -476,11 +479,11 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers, pullData, feed, webpub); - data.prompt.firstSimple.speech.should.to.be.eq('Pick one of these by requesting the corresponding number, or ask for the next set.\n' + + data.prompt.firstSimple.speech.should.to.be.eq('Pick one of these by requesting the corresponding number.\n' + '1. my test title.\n' + '2. my test title.\n' + '3. my test title.\n' + - 'Which one will you choose?\n'); + 'Which number do you choose?\n'); // data.scene.next.name.should.to.be.eq('selection'); }); it('on_enter - groups - state == DEFAULT should throw', async () => { @@ -993,7 +996,7 @@ describe(scene + ' handler', () => { model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(3); // 3 model.data.store.session.scene.selection.url.should.to.be.eq('http://my.url'); // reset - const message = 'no another results available\n'; + const message = 'no another results available.\n'; data.prompt.firstSimple.speech.should.to.be.eq(message); data.scene.next.name.should.to.be.eq('selection'); @@ -1022,7 +1025,7 @@ describe(scene + ' handler', () => { model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(3); // 3 model.data.store.session.scene.selection.url.should.to.be.eq('http://my.url'); // reset - const message = 'no another results available\n'; + const message = 'no another results available.\n'; data.prompt.firstSimple.speech.should.to.be.eq(message); data.scene.next.name.should.to.be.eq('selection'); diff --git a/webhooks/functions/src/tools.ts b/webhooks/functions/src/tools.ts new file mode 100644 index 00000000..e02192ea --- /dev/null +++ b/webhooks/functions/src/tools.ts @@ -0,0 +1,16 @@ + + +export const stall = (fn: (v: string) => Promise) => { + const store = new Map(); + + return async (k: string) => { + const ret = store.get(k); + if (ret) { + return ret; + } + const value = await fn(k); + store.set(k, value); + + return value; + }; +} \ No newline at end of file diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index e5eaf11b..fffcea7d 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -13,7 +13,7 @@ "enter": { "first": { "1": "To fully enjoy your audiobooks and access your personal bookshelf, you will need to link your {{- name}} account.", - "2": "Would you like to do so now ?" + "2": "Would you like to do so now?" } }, "no": { @@ -36,7 +36,7 @@ }, "home_new_user_no": { "help": { - "1": "In order to use the {{- name}} library via your Google Home, you must be a registered member of the library and link your account. Would you like to learn more about the {{- name}} Livrary?" + "1": "In order to use the {{- name}} library via your Google Home, you must be a registered member of the library and link your account. Would you like to learn more about the {{- name}} Library?" } }, "info": { @@ -47,28 +47,31 @@ "1": "If you'd like to learn more about {{- name}} membership, you can ask me by simply saying Yes, or Stop to exit this google application. If you have any other questions, we recommend reaching out to your local library for support. I'm listening?" }, "yesOrMembership": { - "1": "Signing up is easy, you can head on over to the CELA online platform at CELA Library dot c.a. Keep the name of your local library and your library or SQLA number handy, that's all you'll need. You can also ask for help at your local library. As soon as your membership is activated, you can come back to start using the {{- name}} library via Google Assistant, by saying 'Hey Google, launch Accessible reading Canada." + "1": "Signing up is easy, you can head on over to the EDRLAB online platform at celalibrary dot ca. Keep the name of your local library and your library or SQLA number handy, that's all you'll need. You can also ask for help at your local library. As soon as your membership is activated, you can come back to start using the {{- name}} library via Google Assistant, by saying Hey Google, launch Accessible reading Canada." } }, "home_user": { "enter": { "newlyUser": { - "1": "Congratulations! You have succesfully linked your account and can now access all of your favorite books!", - "2": "Would you like to consult your bookshelf, or browse our collections? You can also search for a book by saying search followed by a book title or an author." + "1": "Congratulations! You have succesfully linked your account and can now access all of your favorite books! Remember, you can ask for help at any time.", + "2": "Would you like to consult your bookshelf, or browse our collections? You can also search for a book by saying search for. Followed by a book title or an author." }, "playing": { - "1": "You are listening to the {{- chapterNumber}} chapter of {{- titleAndAuthor}}, which you can pick up where you left off.", + "1": "You are listening to the {{- chapterNumber}} chapter of {{- titleAndAuthor}}, which you can now pick up.", "2": "You are also reading {{- readingNumber}} other recent books, which you can choose from.", - "3": "But there is more:" + "3": "And, of course, " }, "regular": { "1": "You can consult your bookshelf, or browse our collections. You can also search for a book by saying search followed by a book title or an author.", "2": "Resume reading. Recent books. Bookshelf. Collections. Search for a specific book: what do you want to do?" } }, + "currentBook": { + "1": "Uh Oh! Nothing to read here quite yet." + }, "help": { - "1": "You can pick the books you recently listened to with the Recent Books command. You can also check the list of books you have selected with the help of a librarian by the command Bookshelf; browse our predefined collections by the command Collections. Finally, you can search for a book by saying Search followed by a title or part of a title, an author, or both.", - "2": "What do you prefer: Resume reading. Recent books. Bookshelf. Collections or search for a book?" + "1": "At this stage, you can resume your last book with Resume Reading command or pick any books you recently listened to with the Recent Books command. You can also check the list of books you have selected with the help of a librarian by the command Bookshelf; browse our predefined collections by the command Collections. Finally, you can search for a book by saying Search followed by a title or part of a title, an author, or both.", + "2": "What do you prefer: Resume reading. Recent books. Bookshelf. Collections or Search?" } }, "search": { @@ -87,34 +90,36 @@ "first": "Here are the first {{- number}} titles on your bookshelf:", "second": "Or perhaps you'd like to explore the other titles on your bookshelf?" }, - "search": "I found {{- number}} books with that title", + "search": "I found {{- number}} books with that title.", "collection": { - "publication": "I found {{- number}} books", - "group": "I found {{- number}} groups" + "publication": "I found {{- number}} books.", + "group": "I found {{- number}} groups." }, "lastPage": { - "publication": "Here's the last available books", - "group": "Here's the last available groups", - "notAvailable": "no another results available" + "publication": "Here's the last available books.", + "group": "Here's the last available groups.", + "notAvailable": "no another results available." }, "common": { - "1": "Pick one of these by requesting the corresponding number, or ask for the next set.", + "1": "Pick one of these by requesting the corresponding number.", "2": "{{- symbol}}. {{- title}}.", - "3": "Which one will you choose?" + "3": "Which number do you choose?" + }, + "nextPage": { + "1": "Or ask for the next set." }, "empty": { "1": "Uh Oh! Nothing to read here quite yet. Not to worry though, we can fix that right away! Would you like to browse our collections? Or perhaps you'd like to search for a specific book by author or book title?" } }, "help": { - "1": "At this stage, you must choose a title among the proposed set, by mentioning its number, for example number 1. You can request other titles by using the Next or Previous commands.", - "2": "What would you like to do?" + "1": "At this stage, you must choose a title among the proposed set, by mentioning its number, for example number 1. You can request other titles by using the Next or Previous commands." } }, "player": { "explain": "Great choice! Before we start, let me remind you how this reader works. You can put your read on hold at any time by saying 'Hey Google, Pause'. 'Hey Google, Resume' will let you pick up your reading where you last left it. You can also navigate between chapters by saying 'Hey Google, next' or 'Hey Google, previous' at any time. Now, shall we get started with 'A Slow Fire Burning'?", - "start": "Let's start reading {{- title}}", - "start2": "Let's continue reading {{- title}}", + "start": "Let's start reading {{- title}}.", + "start2": "Let's continue reading {{- title}}.", "askResumeLastOffset": "Do you want to pick up where it left off?" }, "collections": { @@ -122,7 +127,7 @@ "1": "Okay, would you prefer to get a choice of collections by theme or by genre?" }, "help": { - "1": "To hear an overview of available themes, say 'theme'. For an overview of available genres, say 'genre'. Do you want to hear a list of available themes or genres?" + "1": "To hear an overview of available themes, say 'by theme'. For an overview of available genres, say 'by genre'." } }, "void": "Bye!", @@ -138,6 +143,6 @@ "2": "Sorry, I really don't hear well." }, "error": { - "1": "Oops, something went wrong. I will send you back to the home menu" + "1": "Oops, something went wrong. I will send you back to the home menu." } } diff --git a/webhooks/functions/src/translation/fr/fr.json b/webhooks/functions/src/translation/fr/fr.json index bf1ce36f..d5b4b5a5 100644 --- a/webhooks/functions/src/translation/fr/fr.json +++ b/webhooks/functions/src/translation/fr/fr.json @@ -2,17 +2,17 @@ "main": { "welcome": { "noLinked": { - "1": "Bienvenue dans la bibliothèque {{- name}}, où vous pouvez accéder facilement à vos livres audios favoris. " + "1": "Bienvenue dans la bibliothèque {{- name}}, où vous pouvez accéder facilement à vos livres favoris. " }, "linked": { - "1": "Bienvenue dans votre bibliothèque {{- name}} ! Rappelez-vous, vous pouvez demander de l'aide à tout instant." + "1": "Bienvenue dans votre bibliothèque {{- name}} !" } } }, "home_new_user": { "enter": { "first": { - "1": "Pour profiter de vos livres audio et accéder à votre liste personnelle, vous devez lier votre compte {{- name}}.", + "1": "Pour profiter de vos livres et accéder à votre liste personnelle, vous devez lier votre compte {{- name}}.", "2": "Voulez-vous le faire maintenant ?" } }, @@ -21,7 +21,7 @@ "2": "Voulez-vous en savoir plus sur l'adhésion à {{- name}} ?" }, "help": { - "1": "Pour découvrir la bibliothèque {{- name}} et profiter de vos livres audio préférés via Google, vous devez connecter votre compte {{- name}}. Pour ce faire, répondez \" oui \" lorsque vous y êtes invité et suivez les instructions. Je vous enverrai alors un lien de connexion, que vous retrouverez dans l'application Google Home. Vous devrez vous connecter à votre compte {{- name}}. Vous n'aurez à le faire qu'une seule fois, et vous serez prêt à commencer à profiter du monde merveilleux des livres de {{- name}} pendant des heures !", + "1": "Pour découvrir la bibliothèque {{- name}} et profiter de vos livres préférés via Google, vous devez connecter votre compte {{- name}}. Pour ce faire, répondez \" oui \" lorsque vous y êtes invité et suivez les instructions. Je vous enverrai alors un lien de connexion, que vous retrouverez dans l'application Google Home. Vous devrez vous connecter à votre compte {{- name}}. Vous n'aurez à le faire qu'une seule fois, et vous pourrez profiter du monde merveilleux des livres de {{- name}} pendant des heures !", "2": "Voulez-vous lier votre compte maintenant ?" }, "maybeLater": { @@ -41,34 +41,37 @@ }, "info": { "about": { - "1": "La bibliothèque {{- name}} est une organisation nationale sans but lucratif créée par les bibliothèques publiques canadiennes pour défendre le droit fondamental des Canadiens souffrant de difficultés de lecture imprimée. Ces personnes peuvent accéder à des publications numériques dans le format de leur choix, y compris l'audio, le braille, le texte électronique et la vidéo descriptive - maintenant aussi disponible via Alexa et Google Home ! Souhaitez-vous en savoir plus sur les possibilité d'inscription à la bibliothèque {{- name}} ?" + "1": "La bibliothèque {{- name}} est une organisation nationale sans but lucratif créée par les bibliothèques publiques canadiennes pour défendre le droit fondamental des Canadiens souffrant de difficultés de lecture sur des supports imprimés. Ces personnes peuvent accéder à des publications numériques dans le format de leur choix, y compris l'audio, le braille, le texte électronique et la vidéo descriptive - maintenant aussi disponible via Alexa et Google Home ! Souhaitez-vous en savoir plus sur les possibilité d'inscription à la bibliothèque {{- name}} ?" }, "help": { "1": "Si vous voulez en savoir plus sur les possibilités d'adhésion à la bibliothèque {{- name}}, vous pouvez le me demander en disant simplement Oui, ou bien Quitter pour quitter cette application. Si vous avez d'autres questions, nous vous recommandons de vous adresser à votre bibliothèque locale pour obtenir de l'aide." }, "yesOrMembership": { - "1": "L'inscription est facile, vous pouvez vous rendre sur la plateforme en ligne de la bibliothèque {{- name}} à l'adresse biblio cahèb point c.a. Gardez à portée de main le nom de votre bibliothèque locale et votre numéro de bibliothèque ou de SQLA, c'est tout ce dont vous aurez besoin. Vous pouvez également demander de l'aide à votre bibliothèque locale. Dès que votre adhésion est activée, vous pouvez revenir pour commencer à utiliser la bibliothèque {{- name}} via Google Assistant, en disant \" Hey Google, je veux parler à Lecture Accessible Canada\"." + "1": "L'inscription est facile, vous pouvez vous rendre sur la plateforme en ligne de la bibliothèque {{- name}} à l'adresse bibliocaeb point ca. Gardez à portée de main le nom de votre bibliothèque locale et votre numéro de bibliothèque ou de SQLA, c'est tout ce dont vous aurez besoin. Vous pouvez également demander de l'aide à votre bibliothèque locale. Dès que votre adhésion est activée, vous pouvez revenir pour commencer à utiliser la bibliothèque {{- name}} via Google Assistant, en disant Hey Google, je veux parler à Lecture Accessible Canada." } }, "home_user": { "enter": { "newlyUser": { - "1": "Félicitations ! Vous avez réussi à connecter votre compte et vous pouvez maintenant accéder à tous vos livres préférés !", + "1": "Félicitations ! Vous avez réussi à connecter votre compte et vous pouvez maintenant accéder à tous vos livres préférés ! Rappelez-vous, vous pouvez demander de l'aide à tout instant.", "2": "Souhaitez-vous consulter votre liste personnelle, ou naviguer dans nos collections ? Vous pouvez également rechercher un livre en prononçant cherche suivi d'un titre de livre ou d'un auteur." }, "playing": { - "1": "Vous êtes en train d'écouter le chapitre {{- chapterNumber}} de {{- titleAndAuthor}}, que vous pouvez reprendre là où vous vous êtes arrêté.", + "1": "Vous êtes en train d'écouter le chapitre {{- chapterNumber}} de {{- titleAndAuthor}}, que vous pouvez reprendre maintenant.", "2": "Vous avez également {{- readingNumber}} autres livres récents, que je peux lister.", - "3": "Mais ce n'est pas tout :" + "3": "Et bien entendu, " }, "regular": { "1": "Vous pouvez consulter votre liste personnelle, ou naviguer dans nos collections. Vous pouvez également rechercher un livre en prononçant cherche suivi d'un titre de livre ou d'un auteur.", "2": "Reprendre la lecture. Livres récents. Liste personnelle. Collections. Chercher un livre : que désirez-vous faire ?" } }, + "currentBook": { + "1": "Il n'y a rien à lire" + }, "help": { - "1": "Vous pouvez consulter les livres récemment écoutés par la commande Mes livres récents. Vous pouvez également consulter la liste des livres que vous avez sélectionnés avec l'aide d'un bibliothécaire par la commande Liste personnelle, naviguer dans nos collections prédéfinies par la commande collections. Vous pouvez enfin rechercher un livre en prononçant Cherche suivi d'un titre ou d'une partie du titre, d'un auteur, ou bien les deux.", - "2": "Que préférez-vous faire : Reprendre la lecture. Livres récents. Liste personnelle. Collections ou chercher un livre ?" + "1": "A cette étape, Vous pouvez reprendre la lecture du livre en cours par la commande Reprendre la lecture, ou consulter les livres récemment écoutés par la commande Mes livres récents. Vous pouvez également consulter la liste des livres que vous avez sélectionnés avec l'aide d'un bibliothécaire par la commande Liste personnelle, naviguer dans nos collections prédéfinies par la commande collections. Vous pouvez enfin rechercher un livre en prononçant Cherche suivi d'un titre ou d'une partie du titre, d'un auteur, ou bien les deux.", + "2": "Que préférez-vous faire : Reprendre la lecture. Livres récents. Liste personnelle. Collections ou Chercher ?" } }, "search": { @@ -87,37 +90,36 @@ "first": "Voici les {{- number}} premiers titres de votre liste personnelle :", "second": "Ou peut-être souhaitez-vous explorer les autres titres de votre liste personnelle ?" }, - "search": "J'ai trouvé {{- number}} livres avec ce titre", + "search": "J'ai trouvé {{- number}} livres avec ce titre.", "collection": { - "publication": "J'ai trouvé {{- number}} livres", - "group": "J'ai trouvé {{- number}} groupes" + "publication": "J'ai trouvé {{- number}} livres.", + "group": "J'ai trouvé {{- number}} groupes." }, "lastPage": { - "publication": "Voici les derniers livres disponibles", - "group": "Voici les derniers groupes disponibles", - "notAvailable": "aucun autre résultat disponible" + "publication": "Voici les derniers livres disponibles:", + "group": "Voici les derniers groupes disponibles:", + "notAvailable": "Aucun autre résultat disponible." }, "common": { - "1": "Choisissez l'un de ces titres en donnant son numéro, ou demandez les éléments suivants.", + "1": "Choisissez l'un de ces éléments en donnant son numéro.", "2": "Numéro {{- symbol}} : {{- title}}.", - "3": "Lequel choisissez-vous ?" + "3": "Quel numéro choisissez-vous ?" }, "nextPage": { - "1": "Ou demandez la page suivante" + "1": "Ou demandez la page suivante." }, "empty": { "1": "En fait, il n'y a rien à lire ici pour le moment. Mais ne vous inquiétez pas, nous pouvons arranger ça tout de suite !" } }, "help": { - "1": "A cette étape, vous devez choisir un titre parmi ceux proposés, en mentionnant son numéro, par exemple numéro 1. Vous pouvez aussi demander d'autres titres par les commandes Suivants ou Précédents.", - "2": "Que souhaitez-vous faire ?" + "1": "A cette étape, vous devez choisir un titre parmi ceux proposés, en mentionnant son numéro, par exemple numéro 1. Vous pouvez aussi demander d'autres titres par les commandes Suivants ou Précédents." } }, "player": { "explain": "Excellent choix ! Avant de commencer, laissez-moi vous rappeler comment fonctionne ce lecteur. Vous pouvez mettre votre lecture en attente à tout moment en disant 'Google, Pause'. 'Google, Lecture' vous permettra de reprendre votre lecture là où vous l'avez pausée. Vous pouvez également naviguer entre les chapitres en disant 'Hey Google, suivant' ou 'Hey Google, précédent' à tout moment.", - "start": "Voici donc {{- title}}", - "start2": "Reprenons la lecture de {{- title}}", + "start": "Voici donc {{- title}}.", + "start2": "Reprenons la lecture de {{- title}}.", "askResumeLastOffset": "Voulez-vous reprendre la lecture là où elle a été interrompue ?" }, "collections": { @@ -125,12 +127,12 @@ "1": "Très bien. Préférez-vous obtenir une sélection de livres par thème ou par genre ?" }, "help": { - "1": "Pour entendre un aperçu des thèmes disponibles, dites thème. Pour un aperçu des genres disponibles, dites genre. Voulez-vous entendre la liste des thèmes ou des genres disponibles ?" + "1": "Pour entendre un aperçu des thèmes disponibles, dites par thème. Pour un aperçu des genres disponibles, dites par genre." } }, "void": "au revoir!", "bye": { - "1": "Très bien. Souvenez-vous : si vous avez besoin d'aide pour utiliser l'application Lecture Accessible Canada, nos bibliothécaires sont à votre service. Nous espérons que vous reviendrez bientôt pour profiter de vos livres audio préférés." + "1": "Très bien. Souvenez-vous : si vous avez besoin d'aide pour utiliser l'application Lecture Accessible Canada, nos bibliothécaires sont à votre service. Nous espérons que vous reviendrez bientôt pour profiter de vos livres préférés." }, "fallback": { "1": "Je n'ai pas compris, que désirez-vous faire ?", diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index 2279f2e6..1cad684a 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.enter.regular.2" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "player.explain" | "player.start" | "player.start2" | "player.askResumeLastOffset" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", - "fr": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.enter.regular.2" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "selection.help.2" | "player.explain" | "player.start" | "player.start2" | "player.askResumeLastOffset" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1" + "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.enter.regular.2" | "home_user.currentBook.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "player.explain" | "player.start" | "player.start2" | "player.askResumeLastOffset" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", + "fr": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.enter.regular.2" | "home_user.currentBook.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "player.explain" | "player.start" | "player.start2" | "player.askResumeLastOffset" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1" }; keysWithNS: { - "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.enter.regular.2" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:search.enter.2" | "en:search.empty.1" | "en:search.empty.2" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:selection.help.2" | "en:player.explain" | "en:player.start" | "en:player.start2" | "en:player.askResumeLastOffset" | "en:collections.enter.1" | "en:collections.help.1" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", - "fr": "fr:main.welcome.noLinked.1" | "fr:main.welcome.linked.1" | "fr:home_new_user.enter.first.1" | "fr:home_new_user.enter.first.2" | "fr:home_new_user.no.1" | "fr:home_new_user.no.2" | "fr:home_new_user.help.1" | "fr:home_new_user.help.2" | "fr:home_new_user.maybeLater.1" | "fr:home_new_user.maybeLater.2" | "fr:home_new_user_maybe_later.help.1" | "fr:home_new_user_no.help.1" | "fr:info.about.1" | "fr:info.help.1" | "fr:info.yesOrMembership.1" | "fr:home_user.enter.newlyUser.1" | "fr:home_user.enter.newlyUser.2" | "fr:home_user.enter.playing.1" | "fr:home_user.enter.playing.2" | "fr:home_user.enter.playing.3" | "fr:home_user.enter.regular.1" | "fr:home_user.enter.regular.2" | "fr:home_user.help.1" | "fr:home_user.help.2" | "fr:search.enter.1" | "fr:search.enter.2" | "fr:search.empty.1" | "fr:search.empty.2" | "fr:selection.enter.bookshelf.first" | "fr:selection.enter.bookshelf.second" | "fr:selection.enter.search" | "fr:selection.enter.collection.publication" | "fr:selection.enter.collection.group" | "fr:selection.enter.lastPage.publication" | "fr:selection.enter.lastPage.group" | "fr:selection.enter.lastPage.notAvailable" | "fr:selection.enter.common.1" | "fr:selection.enter.common.2" | "fr:selection.enter.common.3" | "fr:selection.enter.nextPage.1" | "fr:selection.enter.empty.1" | "fr:selection.help.1" | "fr:selection.help.2" | "fr:player.explain" | "fr:player.start" | "fr:player.start2" | "fr:player.askResumeLastOffset" | "fr:collections.enter.1" | "fr:collections.help.1" | "fr:void" | "fr:bye.1" | "fr:fallback.1" | "fr:fallback.2" | "fr:silence.1" | "fr:silence.2" | "fr:error.1" + "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.enter.regular.2" | "en:home_user.currentBook.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:search.enter.2" | "en:search.empty.1" | "en:search.empty.2" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.nextPage.1" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:player.explain" | "en:player.start" | "en:player.start2" | "en:player.askResumeLastOffset" | "en:collections.enter.1" | "en:collections.help.1" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", + "fr": "fr:main.welcome.noLinked.1" | "fr:main.welcome.linked.1" | "fr:home_new_user.enter.first.1" | "fr:home_new_user.enter.first.2" | "fr:home_new_user.no.1" | "fr:home_new_user.no.2" | "fr:home_new_user.help.1" | "fr:home_new_user.help.2" | "fr:home_new_user.maybeLater.1" | "fr:home_new_user.maybeLater.2" | "fr:home_new_user_maybe_later.help.1" | "fr:home_new_user_no.help.1" | "fr:info.about.1" | "fr:info.help.1" | "fr:info.yesOrMembership.1" | "fr:home_user.enter.newlyUser.1" | "fr:home_user.enter.newlyUser.2" | "fr:home_user.enter.playing.1" | "fr:home_user.enter.playing.2" | "fr:home_user.enter.playing.3" | "fr:home_user.enter.regular.1" | "fr:home_user.enter.regular.2" | "fr:home_user.currentBook.1" | "fr:home_user.help.1" | "fr:home_user.help.2" | "fr:search.enter.1" | "fr:search.enter.2" | "fr:search.empty.1" | "fr:search.empty.2" | "fr:selection.enter.bookshelf.first" | "fr:selection.enter.bookshelf.second" | "fr:selection.enter.search" | "fr:selection.enter.collection.publication" | "fr:selection.enter.collection.group" | "fr:selection.enter.lastPage.publication" | "fr:selection.enter.lastPage.group" | "fr:selection.enter.lastPage.notAvailable" | "fr:selection.enter.common.1" | "fr:selection.enter.common.2" | "fr:selection.enter.common.3" | "fr:selection.enter.nextPage.1" | "fr:selection.enter.empty.1" | "fr:selection.help.1" | "fr:player.explain" | "fr:player.start" | "fr:player.start2" | "fr:player.askResumeLastOffset" | "fr:collections.enter.1" | "fr:collections.help.1" | "fr:void" | "fr:bye.1" | "fr:fallback.1" | "fr:fallback.2" | "fr:silence.1" | "fr:silence.2" | "fr:error.1" }; } diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index 220551af..52b77600 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end' | 'player__on_enter' | 'player__intent__media_status_finished' | 'player__intent__media_status_paused' | 'player__intent__media_status_stopped' | 'player__intent__media_status_failed' | 'search__on_enter' | 'search__intent__search_query' | 'search__intent__search' | 'collections__on_enter' | 'collections__intent__bookshelf' | 'collections__intent__by_genre' | 'collections__intent__by_theme' | 'collections__intent__help' | 'collections__intent__fallback' | 'collections__intent__fallback_end' | 'collections__intent__silence' | 'collections__intent__silence_end' | 'player_prequel__on_enter' | 'player_prequel__intent__yes' | 'player_prequel__intent__no' | 'home_user__intent__recent_books' | 'info__intent__no'; +export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end' | 'player__on_enter' | 'player__intent__media_status_finished' | 'player__intent__media_status_paused' | 'player__intent__media_status_stopped' | 'player__intent__media_status_failed' | 'search__on_enter' | 'search__intent__search_query' | 'search__intent__search' | 'collections__on_enter' | 'collections__intent__bookshelf' | 'collections__intent__by_genre' | 'collections__intent__by_theme' | 'collections__intent__help' | 'collections__intent__fallback' | 'collections__intent__fallback_end' | 'collections__intent__silence' | 'collections__intent__silence_end' | 'player_prequel__on_enter' | 'player_prequel__intent__yes' | 'player_prequel__intent__no' | 'home_user__intent__recent_books' | 'info__intent__no' | 'home_user__intent__current_book'; From ea7d8426b2a29fd712eedcd1a993f3f204bf69f9 Mon Sep 17 00:00:00 2001 From: Pierre Leroux Date: Wed, 6 Apr 2022 16:12:57 +0200 Subject: [PATCH 163/180] feature: enhance player_prequel scene with a summary and in the further with audiobooks info and TOC (PR #78) * first summary * new player_prequel with test ok * lint * sdk: summary * fix: test online * Update en.json Correction of en language * Update fr.json * fix: test Co-authored-by: L. Le Meur --- .../intents/en/player_prequel_back.yaml | 5 + .../intents/en/player_prequel_resume.yaml | 2 + .../intents/en/player_prequel_start.yaml | 3 + .../intents/en/player_prequel_summary.yaml | 6 + sdk/custom/intents/player_prequel_back.yaml | 5 + sdk/custom/intents/player_prequel_resume.yaml | 2 + sdk/custom/intents/player_prequel_start.yaml | 4 + .../intents/player_prequel_summary.yaml | 5 + sdk/custom/scenes/player_prequel.yaml | 38 ++- sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 12 +- webhooks/functions/src/controller/Machine.ts | 89 +++++-- .../src/controller/handler/home_user.ts | 7 +- .../src/controller/handler/player_prequel.ts | 143 ++++++++--- .../src/controller/handler/selection.ts | 4 +- .../functions/src/model/data.model.test.ts | 14 +- webhooks/functions/src/model/storage.dto.ts | 13 +- .../functions/src/model/storage.interface.ts | 8 +- webhooks/functions/src/sdk/home_user.test.ts | 5 - webhooks/functions/src/sdk/player.test.ts | 1 - .../functions/src/sdk/player_prequel.test.ts | 224 +++++++++++++++--- webhooks/functions/src/sdk/selection.test.ts | 14 +- webhooks/functions/src/translation/en/en.json | 23 +- webhooks/functions/src/translation/fr/fr.json | 20 +- webhooks/functions/src/typings/i18n.d.ts | 8 +- .../functions/src/typings/sdkHandler.d.ts | 2 +- 25 files changed, 522 insertions(+), 135 deletions(-) create mode 100644 sdk/custom/intents/en/player_prequel_back.yaml create mode 100644 sdk/custom/intents/en/player_prequel_resume.yaml create mode 100644 sdk/custom/intents/en/player_prequel_start.yaml create mode 100644 sdk/custom/intents/en/player_prequel_summary.yaml create mode 100644 sdk/custom/intents/player_prequel_back.yaml create mode 100644 sdk/custom/intents/player_prequel_resume.yaml create mode 100644 sdk/custom/intents/player_prequel_start.yaml create mode 100644 sdk/custom/intents/player_prequel_summary.yaml diff --git a/sdk/custom/intents/en/player_prequel_back.yaml b/sdk/custom/intents/en/player_prequel_back.yaml new file mode 100644 index 00000000..56fdc838 --- /dev/null +++ b/sdk/custom/intents/en/player_prequel_back.yaml @@ -0,0 +1,5 @@ +trainingPhrases: +- back to collections +- back to selections +- back to the list +- back diff --git a/sdk/custom/intents/en/player_prequel_resume.yaml b/sdk/custom/intents/en/player_prequel_resume.yaml new file mode 100644 index 00000000..97220511 --- /dev/null +++ b/sdk/custom/intents/en/player_prequel_resume.yaml @@ -0,0 +1,2 @@ +trainingPhrases: +- resume reading diff --git a/sdk/custom/intents/en/player_prequel_start.yaml b/sdk/custom/intents/en/player_prequel_start.yaml new file mode 100644 index 00000000..5e4181b4 --- /dev/null +++ b/sdk/custom/intents/en/player_prequel_start.yaml @@ -0,0 +1,3 @@ +trainingPhrases: +- start reading +- start diff --git a/sdk/custom/intents/en/player_prequel_summary.yaml b/sdk/custom/intents/en/player_prequel_summary.yaml new file mode 100644 index 00000000..829997a8 --- /dev/null +++ b/sdk/custom/intents/en/player_prequel_summary.yaml @@ -0,0 +1,6 @@ +trainingPhrases: +- Information +- Info +- Description +- Summarize +- Summary diff --git a/sdk/custom/intents/player_prequel_back.yaml b/sdk/custom/intents/player_prequel_back.yaml new file mode 100644 index 00000000..a33c3b40 --- /dev/null +++ b/sdk/custom/intents/player_prequel_back.yaml @@ -0,0 +1,5 @@ +trainingPhrases: +- Revenir aux sélections +- Revenir aux collections +- Revenir à la liste +- revenir à la liste diff --git a/sdk/custom/intents/player_prequel_resume.yaml b/sdk/custom/intents/player_prequel_resume.yaml new file mode 100644 index 00000000..844e462f --- /dev/null +++ b/sdk/custom/intents/player_prequel_resume.yaml @@ -0,0 +1,2 @@ +trainingPhrases: +- Reprendre la lecture diff --git a/sdk/custom/intents/player_prequel_start.yaml b/sdk/custom/intents/player_prequel_start.yaml new file mode 100644 index 00000000..af23681f --- /dev/null +++ b/sdk/custom/intents/player_prequel_start.yaml @@ -0,0 +1,4 @@ +trainingPhrases: +- commencer la lecture +- démarrer +- démarrer la lecture diff --git a/sdk/custom/intents/player_prequel_summary.yaml b/sdk/custom/intents/player_prequel_summary.yaml new file mode 100644 index 00000000..48c4f922 --- /dev/null +++ b/sdk/custom/intents/player_prequel_summary.yaml @@ -0,0 +1,5 @@ +trainingPhrases: +- information +- info +- écouter le résumé +- résumé diff --git a/sdk/custom/scenes/player_prequel.yaml b/sdk/custom/scenes/player_prequel.yaml index e3439cfa..8ca05d70 100644 --- a/sdk/custom/scenes/player_prequel.yaml +++ b/sdk/custom/scenes/player_prequel.yaml @@ -1,9 +1,39 @@ intentEvents: - handler: - webhookHandler: player_prequel__intent__yes - intent: "yes" + webhookHandler: player_prequel__intent__help + intent: help - handler: - webhookHandler: player_prequel__intent__no - intent: "no" + webhookHandler: player_prequel__intent__repeat + intent: repeat +- handler: + webhookHandler: player_prequel__intent__player_prequel_back + intent: player_prequel_back +- handler: + webhookHandler: player_prequel__intent__player_prequel_resume + intent: player_prequel_resume +- handler: + webhookHandler: player_prequel__intent__player_prequel_start + intent: player_prequel_start +- handler: + webhookHandler: player_prequel__intent__player_prequel_summary + intent: player_prequel_summary +- handler: + webhookHandler: player_prequel__fallback + intent: actions.intent.NO_MATCH_1 +- handler: + webhookHandler: player_prequel__fallback + intent: actions.intent.NO_MATCH_2 +- handler: + webhookHandler: player_prequel__fallback_end + intent: actions.intent.NO_MATCH_FINAL +- handler: + webhookHandler: player_prequel__silence + intent: actions.intent.NO_INPUT_1 +- handler: + webhookHandler: player_prequel__silence + intent: actions.intent.NO_INPUT_2 +- handler: + webhookHandler: player_prequel__silence_end + intent: actions.intent.NO_INPUT_FINAL onEnter: webhookHandler: player_prequel__on_enter diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index 939e1268..bb3bc259 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -81,11 +81,19 @@ handlers: - name: collections__intent__silence - name: collections__intent__silence_end - name: player_prequel__on_enter -- name: player_prequel__intent__yes -- name: player_prequel__intent__no - name: home_user__intent__recent_books - name: info__intent__no - name: home_user__intent__current_book +- name: player_prequel__intent__help +- name: player_prequel__intent__repeat +- name: player_prequel__intent__player_prequel_back +- name: player_prequel__intent__player_prequel_resume +- name: player_prequel__intent__player_prequel_start +- name: player_prequel__intent__player_prequel_summary +- name: player_prequel__fallback +- name: player_prequel__fallback_end +- name: player_prequel__silence +- name: player_prequel__silence_end httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 0388f6b8..1dd1135b 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -99,6 +99,11 @@ export class Machine { this._sayAcc += this._i18n.t(key, options) + '\n'; } + public t(key: TI18nKey, options?: object) { + ok(this._i18n); + return this._i18n.t(key, options); + } + public saidSomething(): boolean { return !!this._sayAcc; } @@ -157,10 +162,6 @@ export class Machine { this._model.store.session.scene[scene].state = state; } - public get playingInProgress() { - ok(this._model); - return this._model.store.player.current.playing; - } public get playingNumber() { ok(this._model); @@ -175,22 +176,22 @@ export class Machine { ); } - public async getCurrentPlayingTitleAndChapter() { + public async getCurrentPlayingInfo(cur = this._model?.store.player.current) { ok(this._model); - - const cur = this._model.store.player.current; + ok(cur); const url = cur.url || ''; const chapter = (cur.index || 0) + 1; - const {title, author} = await this.getTitleAndAuthorFromWebpub(url); + const {title, author, description} = await this.getInfoFromWebpub(url); - return {chapter, title, author}; + return {chapter, title, author, description}; } - public async getTitleAndAuthorFromWebpub(url: string) { + public async getInfoFromWebpub(url: string) { const webpub = await this.webpubRequest(url); const title = webpub?.title || 'no title'; // @TODO i18n const author = (webpub?.authors || [])[0] || ''; - return {title, author}; + const description = (webpub?.description) || ''; + return {title, author, description}; } public debugSelectionSession() { @@ -208,6 +209,16 @@ export class Machine { this._model.store.session.scene.selection = d; } + public get playerPrequelSession() { + ok(this._model); + return this._model.store.session.scene.player_prequel; + } + + public set playerPrequelSession(d: ISessionScene['player_prequel']) { + ok(this._model); + this._model.store.session.scene.player_prequel = d; + } + public get searchSession() { ok(this._model); return this._model.store.session.scene.search; @@ -218,8 +229,8 @@ export class Machine { this._model.store.session.scene.search = d; } - public isCurrentlyPlaying() { - const {url, time, index} = this.playerCurrent; + public isCurrentlyPlaying(c = this.playerCurrent) { + const {url, time, index} = c; // if (!playing) { // return false; // @TODO: need to define the use of this boolean // } @@ -235,6 +246,14 @@ export class Machine { return true; } + public isPlayingAvailableInPlayerPrequelSession() { + return !!this.playerPrequelSession.player.url; + } + + public isCurrentlyPlayingInPlayerPrequelSession() { + return this.isCurrentlyPlaying(this.playerPrequelSession.player); + } + public get playerCurrent() { ok(this._model); return this._model.store.player.current; @@ -318,26 +337,40 @@ export class Machine { if (!this.isValidHttpUrl(webpubUrl)) { throw new Error('webpub url not valid'); } - this.initPlayerCurrentWithWebpubUrl(pub.webpubUrl); - - this.selectionSession.state = 'DEFAULT'; - this.selectionSession.from = 'main'; - this.selectionSession.url = ''; - this.selectionSession.nbChoice = 0; // reset - this.selectionSession.nextUrlCounter = 0; // reset + this.initPlayerInPlayerPrequelSession(pub.webpubUrl); return true; } return false; } - public initPlayerCurrentWithWebpubUrl(webpubUrl: string) { + public resetSelectionSession() { + this.selectionSession.state = 'DEFAULT'; + this.selectionSession.from = 'main'; + this.selectionSession.url = ''; + this.selectionSession.nbChoice = 0; // reset + this.selectionSession.nextUrlCounter = 0; // reset + } + + public initPlayerInPlayerPrequelSession(webpubUrl: string) { ok(this._model); const pubFromHistory = this._model.store.player.history.get(webpubUrl); - this.playerCurrent.index = pubFromHistory?.index ?? 0; - this.playerCurrent.playing = true; - this.playerCurrent.time = pubFromHistory?.time ?? 0; - this.playerCurrent.url = webpubUrl; + this.playerPrequelSession.player = { + url: webpubUrl, + index: pubFromHistory?.index ?? 0, + time: pubFromHistory?.time ?? 0, + }; + } + + public resetPlayerInPLayerPrequelSession() { + this.playerPrequelSession.player = {}; + } + + public initPlayerCurrentWithPlayerPrequelSession() { + const {index, time, url} = this.playerPrequelSession.player; + this.playerCurrent.index = index; + this.playerCurrent.time = time; + this.playerCurrent.url = url; } public async getPublicationFromNumberInSelectionWithUrl(url: string, number: number) { @@ -491,7 +524,6 @@ export class Machine { this._model.store.player.current.index = index; this._model.store.player.current.time = progress; - this._model.store.player.current.playing = true; // always true this._model.store.player.history.set(url, { index, @@ -665,6 +697,11 @@ export class Machine { query: '', from: 'main', }, + 'player_prequel': { + state: 'DEFAULT', + from: 'main', + player: {}, + }, }, }; this._model.store.user.sessionId = id; diff --git a/webhooks/functions/src/controller/handler/home_user.ts b/webhooks/functions/src/controller/handler/home_user.ts index e11d727b..4ab3366d 100644 --- a/webhooks/functions/src/controller/handler/home_user.ts +++ b/webhooks/functions/src/controller/handler/home_user.ts @@ -24,7 +24,7 @@ const enter: THandlerFn = async (m) => { const state = m.getSessionState("home_user"); const newlyLinked = m.authenticationState === "NEWLY_LINKED"; - const playing = m.playingInProgress; + const playing = m.isCurrentlyPlaying(); const regularUser = m.isARegularUser; if (state === "SESSION") { @@ -50,7 +50,7 @@ const enter: THandlerFn = async (m) => { } else if (playing) { - const {title, chapter, author} = await m.getCurrentPlayingTitleAndChapter(); + const {title, chapter, author} = await m.getCurrentPlayingInfo(); const readingNumber = m.playingNumber - 1; m.say("home_user.enter.playing.1", {chapterNumber: chapter, titleAndAuthor: `${title}${author ? `, ${author}` : ''}`}); @@ -112,9 +112,10 @@ const recentBooks: THandlerFn = (m) => { const currentBook: THandlerFn = (m) => { - const isPlaying = m.isCurrentlyPlaying(); + const isPlaying = !!m.currentPlayingUrl; if (isPlaying) { + m.playerPrequelSession.from = "home_user__intent__current_book"; m.nextScene = 'player_prequel'; } else { diff --git a/webhooks/functions/src/controller/handler/player_prequel.ts b/webhooks/functions/src/controller/handler/player_prequel.ts index b37acda6..70d872eb 100644 --- a/webhooks/functions/src/controller/handler/player_prequel.ts +++ b/webhooks/functions/src/controller/handler/player_prequel.ts @@ -1,60 +1,143 @@ -import { THandlerFn } from "../../type"; +import { t } from "i18next"; +import { THandlerFn, TMachine } from "../../type"; +import { TSdkScene } from "../../typings/sdkScene"; import { Assistant } from "../Assistant"; +import { missing } from "./void"; export const player_prequel = (app: Assistant) => { app.handle("player_prequel__on_enter", enter); - app.handle("player_prequel__intent__yes", yes); - app.handle("player_prequel__intent__no", no); + app.handle("player_prequel__intent__player_prequel_summary", summary); + app.handle("player_prequel__intent__player_prequel_back", back); + app.handle("player_prequel__intent__player_prequel_resume", resume); + app.handle("player_prequel__intent__player_prequel_start", start); + app.handle("player_prequel__intent__help", help); + app.handle("player_prequel__intent__repeat", repeat); + app.handle("player_prequel__fallback", help); + app.handle("player_prequel__fallback_end", missing); + app.handle("player_prequel__silence", help); + app.handle("player_prequel__silence_end", help); } const enter: THandlerFn = async (m) => { + + const from = m.playerPrequelSession.from; + // const fromScene = from.split("__")[0] as TSdkScene; + + + // const state = m.getSessionState('player_prequel'); + + console.log(from); - const isPlaying = m.isCurrentlyPlaying(); - const isRegular = m.isARegularUser; - const a = m.playerCurrent.playing; - if (!isRegular || !a) { - m.say("player.explain"); + if (from === "home_user__intent__current_book") { + + // from home user last book + + // go to player direct + // check if playing available + + m.playerPrequelSession.player = m.playerCurrent; + const isPlayingAvailable = m.isPlayingAvailableInPlayerPrequelSession(); + + if (isPlayingAvailable) { + m.playerPrequelSession.from = "main"; + + await startPlaying(true)(m); + return ; + } } + // from selection + + // > vous avez choisi + const { title } = await m.getCurrentPlayingInfo(m.playerPrequelSession.player); + + const isPlaying = m.isCurrentlyPlayingInPlayerPrequelSession(); if (isPlaying) { - m.say("player.askResumeLastOffset"); + m.say("player_prequel.enter.1", { title, resume: m.t('player_prequel.enter.1-continue') }); + m.say("player_prequel.enter.2", { resumeOrStart: m.t('player_prequel.enter.2-continue') }); + } else { - await intro(m); - m.nextScene = "player"; + m.say("player_prequel.enter.1", { title, resume: m.t('player_prequel.enter.1-begin') }); + m.say("player_prequel.enter.2", { resumeOrStart: m.t('player_prequel.enter.2-begin') }); } - m.playerCurrent.playing = true; } -const intro: THandlerFn = async (m) => { +// help scene +// player_prequel.help - const {title} = await m.getCurrentPlayingTitleAndChapter(); - m.say("player.start", {title}); - - - // m.say("player.start2", {title}); -} +// +// A tout moment vous pouvez demandé le lecture du résumé du livre, +// demandé qui l'as écrit, obtenir le temps d'écoute du livre, +// ou tout simplement naviguer dans la table des matiere. -const yes: THandlerFn = async (m) => { - - await intro(m); - m.playerCurrent.playing = true; +const startPlaying = (resume: boolean) => async (m: TMachine) => { + + const isRegular = m.isARegularUser; + if (!isRegular) { + m.say("player.explain"); + } + + m.initPlayerCurrentWithPlayerPrequelSession(); + const { title } = await m.getCurrentPlayingInfo(); + if (resume) { + m.say("player.start2", { title }); + } else { + m.say("player.start", { title }); + } m.nextScene = "player"; + + m.resetPlayerInPLayerPrequelSession(); + m.resetSelectionSession(); } -const no: THandlerFn = async (m) => { +const back: THandlerFn = async (m) => { - m.playerCurrent.index = 0; - m.playerCurrent.time = 0; - - await intro(m); - m.playerCurrent.playing = true; - m.nextScene = "player"; + m.resetPlayerInPLayerPrequelSession(); + m.selectionSession.state = "RUNNING"; + m.selectionSession.nbChoice = 0; + m.nextScene = 'selection'; +}; + +const resume: THandlerFn = async (m) => { + + await startPlaying(true)(m); +}; + +const start: THandlerFn = async (m) => { + + await startPlaying(false)(m); +}; + +const repeat: THandlerFn = async (m) => { + + m.nextScene = "player_prequel"; +} + +const help: THandlerFn = async (m) => { + + // help message + m.say("player_prequel.help.1"); } +const summary: THandlerFn = async (m) => { + + const {description} = await m.getCurrentPlayingInfo(m.playerPrequelSession.player); + + if (!description) { + + // no description + m.say("player_prequel.noSummary"); + } else { + m.say("player_prequel.summarize", {summary: description}); + } + m.say("player_prequel.summary.1"); + // loop + // m.nextScene = 'player_prequel'; +}; \ No newline at end of file diff --git a/webhooks/functions/src/controller/handler/selection.ts b/webhooks/functions/src/controller/handler/selection.ts index f0ac9f3c..a8d40972 100644 --- a/webhooks/functions/src/controller/handler/selection.ts +++ b/webhooks/functions/src/controller/handler/selection.ts @@ -107,12 +107,10 @@ export const enter: THandlerFn = async (m) => { console.log("RUN PUBLICATIONS"); m.nextScene = "selection"; - } else if (state === "DEFAULT" && m.playerCurrent.playing) { + } else if (state === "FINISH" && m.isPlayingAvailableInPlayerPrequelSession()) { console.log("RUN PLAYER"); m.nextScene = "player_prequel"; - // @TODO set the next-scene to player prequel - // lecture en cours ou annonciation du titre } else { throw new Error("indalid finish state " + state); } diff --git a/webhooks/functions/src/model/data.model.test.ts b/webhooks/functions/src/model/data.model.test.ts index 453fa567..f15d500c 100644 --- a/webhooks/functions/src/model/data.model.test.ts +++ b/webhooks/functions/src/model/data.model.test.ts @@ -5,7 +5,7 @@ export const freshDataClone = () => Object.assign({ bearerToken: 'test', player: { current: { - playing: false, + }, history: { @@ -29,6 +29,11 @@ export const freshDataClone = () => Object.assign({ query: '', from: 'main', }, + player_prequel: { + state: 'DEFAULT', + from: 'main', + player: {}, + }, }, }, user: { @@ -41,7 +46,7 @@ export const parsedDataClone = (): IStorage => Object.assign({ bearerToken: 'test', player: { current: { - playing: false, + }, history: new Map(), }, @@ -63,6 +68,11 @@ export const parsedDataClone = (): IStorage => Object.assign({ query: '', from: 'main', }, + player_prequel: { + state: 'DEFAULT', + from: 'main', + player: {}, + }, }, }, user: { diff --git a/webhooks/functions/src/model/storage.dto.ts b/webhooks/functions/src/model/storage.dto.ts index 5a91da0a..138eb6c2 100644 --- a/webhooks/functions/src/model/storage.dto.ts +++ b/webhooks/functions/src/model/storage.dto.ts @@ -1,7 +1,7 @@ import * as util from 'util'; import {ISessionScene, IStorage, IStoragePlayer, IStoragePlayerCurrent, IStoragePlayerHistory, IStorageSession, IStorageUser, TStateAuthentication} from './storage.interface'; import {classToPlain, Exclude, plainToClass, Transform, TransformationType, Type} from 'class-transformer'; -import {Equals, IsBoolean, IsDate, IsNotEmpty, IsNumber, IsObject, IsOptional, IsString, IsUrl, Min, ValidateNested, validateSync} from 'class-validator'; +import {Equals, IsDate, IsNotEmpty, IsNumber, IsObject, IsOptional, IsString, IsUrl, Min, ValidateNested, validateSync} from 'class-validator'; import {resetSelection} from '../controller/handler/selection.helper'; const DB_VERSION = 1; @@ -41,8 +41,8 @@ class StoragePlayerCurrentDto implements IStoragePlayerCurrent { @IsOptional() url?: string; - @IsBoolean() - playing: boolean; + // @IsBoolean() + // playing: boolean; // set(data: IStoragePlayerCurrent) { // this.index = data.index; @@ -52,7 +52,7 @@ class StoragePlayerCurrentDto implements IStoragePlayerCurrent { // } constructor() { - this.playing = false; + // this.playing = false; } } @@ -100,6 +100,11 @@ class StorageSessionDto implements IStorageSession { query: '', from: 'main', }, + 'player_prequel': { + state: 'DEFAULT', + from: 'main', + player: {}, + }, }; } } diff --git a/webhooks/functions/src/model/storage.interface.ts b/webhooks/functions/src/model/storage.interface.ts index ef0e2ced..5a7bca6a 100644 --- a/webhooks/functions/src/model/storage.interface.ts +++ b/webhooks/functions/src/model/storage.interface.ts @@ -10,7 +10,7 @@ export interface IStoragePlayerCurrent { index?: number; time?: number; url?: string; - playing: boolean; + // playing: boolean; } export interface IStoragePlayer { @@ -24,6 +24,7 @@ export type TStateHomeUser = 'SESSION' | 'REPEAT' | TStateDefault; export type TStateSelection = 'RUNNING' | 'FINISH' | TStateDefault; export type TKindSelection = 'PUBLICATION' | 'GROUP'; export type TStateSearch = 'RUNNING' | 'FINISH' | TStateDefault; +export type TStatePlayerPrequel = TStateDefault; export interface ISessionScene { 'home_user': { @@ -41,6 +42,11 @@ export interface ISessionScene { state: TStateSearch, query: string, from: TSdkHandler, + }, + 'player_prequel': { + state: TStatePlayerPrequel, + from: TSdkHandler, + player: IStoragePlayerCurrent, } } export type TKeySessionScene = keyof ISessionScene; diff --git a/webhooks/functions/src/sdk/home_user.test.ts b/webhooks/functions/src/sdk/home_user.test.ts index 378e9c90..7ddad13f 100644 --- a/webhooks/functions/src/sdk/home_user.test.ts +++ b/webhooks/functions/src/sdk/home_user.test.ts @@ -123,8 +123,6 @@ describe('home_user handler', () => { pullData.player.current.index = 9; pullData.player.current.url = 'https://my.url'; pullData.player.current.time = 0; - pullData.player.current.playing = true; - const webpub: Partial<IWebPubView> = { title: 'my title', @@ -151,7 +149,6 @@ describe('home_user handler', () => { pullData.player.current.index = 9; pullData.player.current.url = 'https://my.url'; pullData.player.current.time = 0; - pullData.player.current.playing = true; pullData.player.history = { // @ts-ignore @@ -237,7 +234,6 @@ describe('home_user handler', () => { pullData.player.current.index = 9; pullData.player.current.url = 'https://my.url'; pullData.player.current.time = 0; - pullData.player.current.playing = false; pullData.player.history = { // @ts-ignore @@ -276,7 +272,6 @@ describe('home_user handler', () => { pullData.player.current.index = 9; pullData.player.current.url = 'https://my.url'; pullData.player.current.time = 0; - pullData.player.current.playing = false; const model = await storageModelMocked(pullData); const data = await expressMocked(body, headers, undefined, undefined, undefined, model.data); diff --git a/webhooks/functions/src/sdk/player.test.ts b/webhooks/functions/src/sdk/player.test.ts index 2114f8e6..aa462a8a 100644 --- a/webhooks/functions/src/sdk/player.test.ts +++ b/webhooks/functions/src/sdk/player.test.ts @@ -68,7 +68,6 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); model.data.store.player.current.index = 2; - model.data.store.player.current.playing.should.to.be.eq(true); model.data.store.player.current.time?.should.to.be.eq(40); model.data.store.player.current.url?.should.to.be.eq('http://my.url'); }); diff --git a/webhooks/functions/src/sdk/player_prequel.test.ts b/webhooks/functions/src/sdk/player_prequel.test.ts index 2031f97e..e67f303f 100644 --- a/webhooks/functions/src/sdk/player_prequel.test.ts +++ b/webhooks/functions/src/sdk/player_prequel.test.ts @@ -12,11 +12,41 @@ const scene = 'player_prequel'; const yaml = `intentEvents: - handler: - webhookHandler: player_prequel__intent__yes - intent: "yes" + webhookHandler: player_prequel__intent__help + intent: help - handler: - webhookHandler: player_prequel__intent__no - intent: "no" + webhookHandler: player_prequel__intent__repeat + intent: repeat +- handler: + webhookHandler: player_prequel__intent__player_prequel_back + intent: player_prequel_back +- handler: + webhookHandler: player_prequel__intent__player_prequel_resume + intent: player_prequel_resume +- handler: + webhookHandler: player_prequel__intent__player_prequel_start + intent: player_prequel_start +- handler: + webhookHandler: player_prequel__intent__player_prequel_summary + intent: player_prequel_summary +- handler: + webhookHandler: player_prequel__fallback + intent: actions.intent.NO_MATCH_1 +- handler: + webhookHandler: player_prequel__fallback + intent: actions.intent.NO_MATCH_2 +- handler: + webhookHandler: player_prequel__fallback_end + intent: actions.intent.NO_MATCH_FINAL +- handler: + webhookHandler: player_prequel__silence + intent: actions.intent.NO_INPUT_1 +- handler: + webhookHandler: player_prequel__silence + intent: actions.intent.NO_INPUT_2 +- handler: + webhookHandler: player_prequel__silence_end + intent: actions.intent.NO_INPUT_FINAL onEnter: webhookHandler: player_prequel__on_enter `; @@ -31,7 +61,7 @@ describe(scene + ' handler', () => { }); describe('app', () => { - it('on enter - no need to ask to resume bad url', async () => { + it('on enter - bad url', async () => { body.handler.name = 'player_prequel__on_enter'; body.scene.name = scene; @@ -45,13 +75,12 @@ describe(scene + ' handler', () => { data.prompt.firstSimple.speech.should.to.be.eq(message); data.scene.next.name.should.to.be.eq('actions.scene.END_CONVERSATION'); }); - it('on enter - no need to ask to resume - start from scratch', async () => { + it('on enter - home_user_current_book', async () => { body.handler.name = 'player_prequel__on_enter'; body.scene.name = scene; const pullData = parsedDataClone(); pullData.player.current.index = 0; - pullData.player.current.playing = false; pullData.player.current.time = 0; pullData.player.current.url = 'http://my.url'; @@ -63,21 +92,27 @@ describe(scene + ' handler', () => { ], }; + pullData.session.scene.player_prequel.from = 'home_user__intent__current_book'; + const model = await storageModelMocked(pullData); const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); data.scene.next.name.should.to.be.eq('player'); + + model.data.store.session.scene.player_prequel.from.should.to.be.eq('main'); + model.data.store.session.scene.player_prequel.player.should.to.be.deep.eq({}); ; + model.data.store.player.current.should.to.be.deep.eq(pullData.player.current); }); - it('on enter - need to ask - and answer yes or no', async () => { + it('on enter - from selection and playing', async () => { body.handler.name = 'player_prequel__on_enter'; body.scene.name = scene; const pullData = parsedDataClone(); - pullData.player.current.index = 2; - pullData.player.current.playing = false; - pullData.player.current.time = 330; - pullData.player.current.url = 'http://my.url'; + pullData.session.scene.player_prequel.player.index = 2; + pullData.session.scene.player_prequel.player.time = 330; + pullData.session.scene.player_prequel.player.url = 'https://my.url'; + pullData.session.scene.player_prequel.from = 'selection__on_enter'; const webpub: Partial<IWebPubView> = { title: 'my title', authors: [ @@ -89,20 +124,65 @@ describe(scene + ' handler', () => { const model = await storageModelMocked(pullData); const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); - data.prompt.firstSimple.speech.should.to.be.eq('Great choice! Before we start, let me remind you how this reader works. You can put your read on hold at any time by saying \'Hey Google, Pause\'. \'Hey Google, Resume\' will let you pick up your reading where you last left it. You can also navigate between chapters by saying \'Hey Google, next\' or \'Hey Google, previous\' at any time. Now, shall we get started with \'A Slow Fire Burning\'?\n' + - 'Do you want to pick up where it left off?\n'); + (typeof model.data.store.player.current.index).should.be.eq('undefined'); + (typeof model.data.store.player.current.time).should.be.eq('undefined'); + (typeof model.data.store.player.current.url).should.be.eq('undefined'); + + model.data.store.session.scene.player_prequel.player.index?.should.be.eq(2); + model.data.store.session.scene.player_prequel.player.time?.should.be.eq(330); + model.data.store.session.scene.player_prequel.player.url?.should.be.eq('https://my.url'); + model.data.store.session.scene.player_prequel.from.should.be.eq('selection__on_enter'); + + data.prompt.firstSimple.speech.should.to.be.eq('You\'ve chosen my title, that you have already started.\n' + + 'Do you want to resume reading, listen the summary or come back to the list?\n'); }); + it('on enter - from selection and no playing', async () => { + body.handler.name = 'player_prequel__on_enter'; + body.scene.name = scene; - it('no', async () => { - body.handler.name = 'player_prequel__intent__no'; + const pullData = parsedDataClone(); + pullData.session.scene.player_prequel.player.index = 0; + pullData.session.scene.player_prequel.player.time = 0; + pullData.session.scene.player_prequel.player.url = 'https://my.url'; + + pullData.session.scene.player_prequel.from = 'selection__on_enter'; + const webpub: Partial<IWebPubView> = { + title: 'my title', + authors: [ + 'hello', + 'world', + ], + }; + + const model = await storageModelMocked(pullData); + const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); + + (typeof model.data.store.player.current.index).should.be.eq('undefined'); + (typeof model.data.store.player.current.time).should.be.eq('undefined'); + (typeof model.data.store.player.current.url).should.be.eq('undefined'); + + // @ts-ignore + model.data.store.session.scene.player_prequel.player.index.should.be.eq(0); + // @ts-ignore + model.data.store.session.scene.player_prequel.player.time.should.be.eq(0); + // @ts-ignore + model.data.store.session.scene.player_prequel.player.url.should.be.eq('https://my.url'); + model.data.store.session.scene.player_prequel.from.should.be.eq('selection__on_enter'); + + data.prompt.firstSimple.speech.should.to.be.eq('You\'ve chosen my title.\n' + + 'Do you want to start reading, listen the summary or come back to the list?\n'); + }); + + it('back', async () => { + body.handler.name = 'player_prequel__intent__player_prequel_back'; body.scene.name = scene; const pullData = parsedDataClone(); - pullData.player.current.index = 2; - pullData.player.current.playing = false; - pullData.player.current.time = 330; - pullData.player.current.url = 'http://my.url'; + pullData.session.scene.player_prequel.player.index = 0; + pullData.session.scene.player_prequel.player.time = 0; + pullData.session.scene.player_prequel.player.url = 'https://my.url'; + pullData.session.scene.player_prequel.from = 'selection__on_enter'; const webpub: Partial<IWebPubView> = { title: 'my title', authors: [ @@ -114,23 +194,24 @@ describe(scene + ' handler', () => { const model = await storageModelMocked(pullData); const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); - model.data.store.player.current.index?.should.to.be.eq(0); - model.data.store.player.current.playing.should.to.be.eq(true); - model.data.store.player.current.url?.should.to.be.eq('http://my.url'); - model.data.store.player.current.time?.should.to.be.eq(0); - data.scene.next.name.should.to.be.eq('player'); + (typeof model.data.store.session.scene.player_prequel.player.index).should.be.eq('undefined'); + (typeof model.data.store.session.scene.player_prequel.player.time).should.be.eq('undefined'); + (typeof model.data.store.session.scene.player_prequel.player.url).should.be.eq('undefined'); + model.data.store.session.scene.player_prequel.from.should.be.eq('selection__on_enter'); + + data.scene.next.name.should.to.be.eq('selection'); }); - it('yes', async () => { - body.handler.name = 'player_prequel__intent__yes'; + it('start', async () => { + body.handler.name = 'player_prequel__intent__player_prequel_start'; body.scene.name = scene; const pullData = parsedDataClone(); - pullData.player.current.index = 2; - pullData.player.current.playing = false; - pullData.player.current.time = 330; - pullData.player.current.url = 'http://my.url'; + pullData.session.scene.player_prequel.player.index = 0; + pullData.session.scene.player_prequel.player.time = 0; + pullData.session.scene.player_prequel.player.url = 'https://my.url'; + pullData.session.scene.player_prequel.from = 'selection__on_enter'; const webpub: Partial<IWebPubView> = { title: 'my title', authors: [ @@ -142,11 +223,84 @@ describe(scene + ' handler', () => { const model = await storageModelMocked(pullData); const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); - model.data.store.player.current.index?.should.to.be.eq(2); - model.data.store.player.current.playing.should.to.be.eq(true); - model.data.store.player.current.url?.should.to.be.eq('http://my.url'); - model.data.store.player.current.time?.should.to.be.eq(330); + (typeof model.data.store.session.scene.player_prequel.player.index).should.be.eq('undefined'); + (typeof model.data.store.session.scene.player_prequel.player.time).should.be.eq('undefined'); + (typeof model.data.store.session.scene.player_prequel.player.url).should.be.eq('undefined'); + model.data.store.session.scene.player_prequel.from.should.be.eq('selection__on_enter'); + + // @ts-ignore + model.data.store.player.current.index.should.be.eq(0); + // @ts-ignore + model.data.store.player.current.time.should.be.eq(0); + // @ts-ignore + model.data.store.player.current.url.should.be.eq('https://my.url'); + + data.scene.next.name.should.to.be.eq('player'); + + data.prompt.firstSimple.speech.should.to.be.eq('Great choice! Before we start, let me remind you how this reader works. You can put your read on hold at any time by saying \'Hey Google, Pause\'. \'Hey Google, Resume\' will let you pick up your reading where you last left it. You can also navigate between chapters by saying \'Hey Google, next\' or \'Hey Google, previous\' at any time.\n' + + 'Let\'s start reading my title.\n'); + }); + it('resume', async () => { + body.handler.name = 'player_prequel__intent__player_prequel_start'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + pullData.session.scene.player_prequel.player.index = 234; + pullData.session.scene.player_prequel.player.time = 435; + pullData.session.scene.player_prequel.player.url = 'https://my.url'; + + pullData.session.scene.player_prequel.from = 'selection__on_enter'; + const webpub: Partial<IWebPubView> = { + title: 'my title', + authors: [ + 'hello', + 'world', + ], + }; + + const model = await storageModelMocked(pullData); + const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); + + (typeof model.data.store.session.scene.player_prequel.player.index).should.be.eq('undefined'); + (typeof model.data.store.session.scene.player_prequel.player.time).should.be.eq('undefined'); + (typeof model.data.store.session.scene.player_prequel.player.url).should.be.eq('undefined'); + model.data.store.session.scene.player_prequel.from.should.be.eq('selection__on_enter'); + + // @ts-ignore + model.data.store.player.current.index.should.be.eq(234); + // @ts-ignore + model.data.store.player.current.time.should.be.eq(435); + // @ts-ignore + model.data.store.player.current.url.should.be.eq('https://my.url'); + data.scene.next.name.should.to.be.eq('player'); + + data.prompt.firstSimple.speech.should.to.be.eq('Great choice! Before we start, let me remind you how this reader works. You can put your read on hold at any time by saying \'Hey Google, Pause\'. \'Hey Google, Resume\' will let you pick up your reading where you last left it. You can also navigate between chapters by saying \'Hey Google, next\' or \'Hey Google, previous\' at any time.\n' + + 'Let\'s start reading my title.\n'); + }); + it('summary', async () => { + body.handler.name = 'player_prequel__intent__player_prequel_summary'; + body.scene.name = scene; + + const pullData = parsedDataClone(); + pullData.session.scene.player_prequel.player.index = 234; + pullData.session.scene.player_prequel.player.time = 435; + pullData.session.scene.player_prequel.player.url = 'https://my.url'; + + pullData.session.scene.player_prequel.from = 'selection__on_enter'; + const webpub: Partial<IWebPubView> = { + title: 'my title', + authors: [ + 'hello', + 'world', + ], + description: 'this the world', + }; + + const model = await storageModelMocked(pullData); + const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); + + data.prompt.firstSimple.speech.should.to.be.eq('Here is the summary: this the world.\nDo you want to start reading or go back to the list?\n'); }); }); }); diff --git a/webhooks/functions/src/sdk/selection.test.ts b/webhooks/functions/src/sdk/selection.test.ts index 8c75d3c4..7421621c 100644 --- a/webhooks/functions/src/sdk/selection.test.ts +++ b/webhooks/functions/src/sdk/selection.test.ts @@ -586,12 +586,11 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); data.scene.next.name.should.to.be.eq('player_prequel'); - model.data.store.session.scene.selection.state.should.to.be.eq('DEFAULT'); - model.data.store.session.scene.selection.url.should.to.be.eq(''); - model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); + model.data.store.session.scene.selection.state.should.to.be.eq('FINISH'); + model.data.store.session.scene.selection.url.should.to.be.eq('http://my.url'); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(1); model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(0); model.data.store.session.scene.selection.from.should.to.be.eq('main'); - model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); }); it('select book - number 2 ', async () => { body.handler.name = 'selection__intent__selects_book'; @@ -613,12 +612,11 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers, undefined, feed, undefined, model.data); data.scene.next.name.should.to.be.eq('player_prequel'); - model.data.store.session.scene.selection.state.should.to.be.eq('DEFAULT'); - model.data.store.session.scene.selection.url.should.to.be.eq(''); - model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); + model.data.store.session.scene.selection.state.should.to.be.eq('FINISH'); + model.data.store.session.scene.selection.url.should.to.be.eq('http://my.url'); + model.data.store.session.scene.selection.nbChoice.should.to.be.eq(2); model.data.store.session.scene.selection.nextUrlCounter.should.to.be.eq(0); model.data.store.session.scene.selection.from.should.to.be.eq('main'); - model.data.store.session.scene.selection.nbChoice.should.to.be.eq(0); }); it('select book - number 3 with only 2 pub available', async () => { diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index fffcea7d..4003be8c 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -116,11 +116,28 @@ "1": "At this stage, you must choose a title among the proposed set, by mentioning its number, for example number 1. You can request other titles by using the Next or Previous commands." } }, + "player_prequel": { + "summarize": "Here is the summary: {{- summary}}.", + "noSummary": "No summary is available, sorry.", + "help": { + "1": "At any time you can ask for the summary of the book, ask for the author or get the remaining listening time." + }, + "enter": { + "1": "You've chosen {{- title}}{{- resume}}", + "1-continue": ", that you have already started.", + "1-begin": ".", + "2": "{{- resumeOrStart}}, listen the summary or come back to the list?", + "2-continue": "Do you want to resume reading", + "2-begin": "Do you want to start reading" + }, + "summary": { + "1": "Do you want to start reading or go back to the list?" + } + }, "player": { - "explain": "Great choice! Before we start, let me remind you how this reader works. You can put your read on hold at any time by saying 'Hey Google, Pause'. 'Hey Google, Resume' will let you pick up your reading where you last left it. You can also navigate between chapters by saying 'Hey Google, next' or 'Hey Google, previous' at any time. Now, shall we get started with 'A Slow Fire Burning'?", + "explain": "Great choice! Before we start, let me remind you how this reader works. You can put your read on hold at any time by saying 'Hey Google, Pause'. 'Hey Google, Resume' will let you pick up your reading where you last left it. You can also navigate between chapters by saying 'Hey Google, next' or 'Hey Google, previous' at any time.", "start": "Let's start reading {{- title}}.", - "start2": "Let's continue reading {{- title}}.", - "askResumeLastOffset": "Do you want to pick up where it left off?" + "start2": "Let's continue reading {{- title}}." }, "collections": { "enter": { diff --git a/webhooks/functions/src/translation/fr/fr.json b/webhooks/functions/src/translation/fr/fr.json index d5b4b5a5..f95deb98 100644 --- a/webhooks/functions/src/translation/fr/fr.json +++ b/webhooks/functions/src/translation/fr/fr.json @@ -116,11 +116,25 @@ "1": "A cette étape, vous devez choisir un titre parmi ceux proposés, en mentionnant son numéro, par exemple numéro 1. Vous pouvez aussi demander d'autres titres par les commandes Suivants ou Précédents." } }, + "player_prequel": { + "summarize": "Voici le résumé: {{- summary}}.", + "noSummary": "Aucun résumé n'est disponible, j'en suis désolé.", + "help": { + "1": "A tout moment vous pouvez demander la lecture du résumé du livre , demander son auteur ou obtenir le temps d'écoute restant." + }, + "enter": { + "1": "Vous avez choisi {{- title}}{{- resume}}", + "1-continue": " que vous aviez déja commencé.", + "1-begin": ".", + "2": "{{- resumeOrStart}}, écouter le résumé, ou revenir à la liste précédente ?", + "2-continue": "Voulez-vous reprendre la lecture", + "2-begin": "Voulez-vous commencer la lecture" + } + }, "player": { "explain": "Excellent choix ! Avant de commencer, laissez-moi vous rappeler comment fonctionne ce lecteur. Vous pouvez mettre votre lecture en attente à tout moment en disant 'Google, Pause'. 'Google, Lecture' vous permettra de reprendre votre lecture là où vous l'avez pausée. Vous pouvez également naviguer entre les chapitres en disant 'Hey Google, suivant' ou 'Hey Google, précédent' à tout moment.", "start": "Voici donc {{- title}}.", - "start2": "Reprenons la lecture de {{- title}}.", - "askResumeLastOffset": "Voulez-vous reprendre la lecture là où elle a été interrompue ?" + "start2": "Reprenons la lecture de {{- title}}." }, "collections": { "enter": { @@ -145,4 +159,4 @@ "error": { "1": "Oups, quelque chose s'est mal passé. Je vous renvoie au menu d'accueil." } -} \ No newline at end of file +} diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index 1cad684a..a971106e 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.enter.regular.2" | "home_user.currentBook.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "player.explain" | "player.start" | "player.start2" | "player.askResumeLastOffset" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", - "fr": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.enter.regular.2" | "home_user.currentBook.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "player.explain" | "player.start" | "player.start2" | "player.askResumeLastOffset" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1" + "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.enter.regular.2" | "home_user.currentBook.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "player_prequel.summarize" | "player_prequel.noSummary" | "player_prequel.help.1" | "player_prequel.enter.1" | "player_prequel.enter.2" | "player_prequel.enter.1-continue" | "player_prequel.enter.1-begin" | "player_prequel.enter.2-continue" | "player_prequel.enter.2-begin" | "player_prequel.summary.1" | "player_prequel.summary.1-continue" | "player_prequel.summary.1-begin" | "player.explain" | "player.start" | "player.start2" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", + "fr": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.enter.regular.2" | "home_user.currentBook.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "player_prequel.summarize" | "player_prequel.noSummary" | "player_prequel.help.1" | "player_prequel.enter.1" | "player_prequel.enter.2" | "player_prequel.enter.1-continue" | "player_prequel.enter.1-begin" | "player_prequel.enter.2-continue" | "player_prequel.enter.2-begin" | "player.explain" | "player.start" | "player.start2" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1" }; keysWithNS: { - "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.enter.regular.2" | "en:home_user.currentBook.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:search.enter.2" | "en:search.empty.1" | "en:search.empty.2" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.nextPage.1" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:player.explain" | "en:player.start" | "en:player.start2" | "en:player.askResumeLastOffset" | "en:collections.enter.1" | "en:collections.help.1" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", - "fr": "fr:main.welcome.noLinked.1" | "fr:main.welcome.linked.1" | "fr:home_new_user.enter.first.1" | "fr:home_new_user.enter.first.2" | "fr:home_new_user.no.1" | "fr:home_new_user.no.2" | "fr:home_new_user.help.1" | "fr:home_new_user.help.2" | "fr:home_new_user.maybeLater.1" | "fr:home_new_user.maybeLater.2" | "fr:home_new_user_maybe_later.help.1" | "fr:home_new_user_no.help.1" | "fr:info.about.1" | "fr:info.help.1" | "fr:info.yesOrMembership.1" | "fr:home_user.enter.newlyUser.1" | "fr:home_user.enter.newlyUser.2" | "fr:home_user.enter.playing.1" | "fr:home_user.enter.playing.2" | "fr:home_user.enter.playing.3" | "fr:home_user.enter.regular.1" | "fr:home_user.enter.regular.2" | "fr:home_user.currentBook.1" | "fr:home_user.help.1" | "fr:home_user.help.2" | "fr:search.enter.1" | "fr:search.enter.2" | "fr:search.empty.1" | "fr:search.empty.2" | "fr:selection.enter.bookshelf.first" | "fr:selection.enter.bookshelf.second" | "fr:selection.enter.search" | "fr:selection.enter.collection.publication" | "fr:selection.enter.collection.group" | "fr:selection.enter.lastPage.publication" | "fr:selection.enter.lastPage.group" | "fr:selection.enter.lastPage.notAvailable" | "fr:selection.enter.common.1" | "fr:selection.enter.common.2" | "fr:selection.enter.common.3" | "fr:selection.enter.nextPage.1" | "fr:selection.enter.empty.1" | "fr:selection.help.1" | "fr:player.explain" | "fr:player.start" | "fr:player.start2" | "fr:player.askResumeLastOffset" | "fr:collections.enter.1" | "fr:collections.help.1" | "fr:void" | "fr:bye.1" | "fr:fallback.1" | "fr:fallback.2" | "fr:silence.1" | "fr:silence.2" | "fr:error.1" + "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.enter.regular.2" | "en:home_user.currentBook.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:search.enter.2" | "en:search.empty.1" | "en:search.empty.2" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.nextPage.1" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:player_prequel.summarize" | "en:player_prequel.noSummary" | "en:player_prequel.help.1" | "en:player_prequel.enter.1" | "en:player_prequel.enter.2" | "en:player_prequel.enter.1-continue" | "en:player_prequel.enter.1-begin" | "en:player_prequel.enter.2-continue" | "en:player_prequel.enter.2-begin" | "en:player_prequel.summary.1" | "en:player_prequel.summary.1-continue" | "en:player_prequel.summary.1-begin" | "en:player.explain" | "en:player.start" | "en:player.start2" | "en:collections.enter.1" | "en:collections.help.1" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", + "fr": "fr:main.welcome.noLinked.1" | "fr:main.welcome.linked.1" | "fr:home_new_user.enter.first.1" | "fr:home_new_user.enter.first.2" | "fr:home_new_user.no.1" | "fr:home_new_user.no.2" | "fr:home_new_user.help.1" | "fr:home_new_user.help.2" | "fr:home_new_user.maybeLater.1" | "fr:home_new_user.maybeLater.2" | "fr:home_new_user_maybe_later.help.1" | "fr:home_new_user_no.help.1" | "fr:info.about.1" | "fr:info.help.1" | "fr:info.yesOrMembership.1" | "fr:home_user.enter.newlyUser.1" | "fr:home_user.enter.newlyUser.2" | "fr:home_user.enter.playing.1" | "fr:home_user.enter.playing.2" | "fr:home_user.enter.playing.3" | "fr:home_user.enter.regular.1" | "fr:home_user.enter.regular.2" | "fr:home_user.currentBook.1" | "fr:home_user.help.1" | "fr:home_user.help.2" | "fr:search.enter.1" | "fr:search.enter.2" | "fr:search.empty.1" | "fr:search.empty.2" | "fr:selection.enter.bookshelf.first" | "fr:selection.enter.bookshelf.second" | "fr:selection.enter.search" | "fr:selection.enter.collection.publication" | "fr:selection.enter.collection.group" | "fr:selection.enter.lastPage.publication" | "fr:selection.enter.lastPage.group" | "fr:selection.enter.lastPage.notAvailable" | "fr:selection.enter.common.1" | "fr:selection.enter.common.2" | "fr:selection.enter.common.3" | "fr:selection.enter.nextPage.1" | "fr:selection.enter.empty.1" | "fr:selection.help.1" | "fr:player_prequel.summarize" | "fr:player_prequel.noSummary" | "fr:player_prequel.help.1" | "fr:player_prequel.enter.1" | "fr:player_prequel.enter.2" | "fr:player_prequel.enter.1-continue" | "fr:player_prequel.enter.1-begin" | "fr:player_prequel.enter.2-continue" | "fr:player_prequel.enter.2-begin" | "fr:player.explain" | "fr:player.start" | "fr:player.start2" | "fr:collections.enter.1" | "fr:collections.help.1" | "fr:void" | "fr:bye.1" | "fr:fallback.1" | "fr:fallback.2" | "fr:silence.1" | "fr:silence.2" | "fr:error.1" }; } diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index 52b77600..81e85714 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end' | 'player__on_enter' | 'player__intent__media_status_finished' | 'player__intent__media_status_paused' | 'player__intent__media_status_stopped' | 'player__intent__media_status_failed' | 'search__on_enter' | 'search__intent__search_query' | 'search__intent__search' | 'collections__on_enter' | 'collections__intent__bookshelf' | 'collections__intent__by_genre' | 'collections__intent__by_theme' | 'collections__intent__help' | 'collections__intent__fallback' | 'collections__intent__fallback_end' | 'collections__intent__silence' | 'collections__intent__silence_end' | 'player_prequel__on_enter' | 'player_prequel__intent__yes' | 'player_prequel__intent__no' | 'home_user__intent__recent_books' | 'info__intent__no' | 'home_user__intent__current_book'; +export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end' | 'player__on_enter' | 'player__intent__media_status_finished' | 'player__intent__media_status_paused' | 'player__intent__media_status_stopped' | 'player__intent__media_status_failed' | 'search__on_enter' | 'search__intent__search_query' | 'search__intent__search' | 'collections__on_enter' | 'collections__intent__bookshelf' | 'collections__intent__by_genre' | 'collections__intent__by_theme' | 'collections__intent__help' | 'collections__intent__fallback' | 'collections__intent__fallback_end' | 'collections__intent__silence' | 'collections__intent__silence_end' | 'player_prequel__on_enter' | 'home_user__intent__recent_books' | 'info__intent__no' | 'home_user__intent__current_book' | 'player_prequel__intent__help' | 'player_prequel__intent__repeat' | 'player_prequel__intent__player_prequel_back' | 'player_prequel__intent__player_prequel_resume' | 'player_prequel__intent__player_prequel_start' | 'player_prequel__intent__player_prequel_summary' | 'player_prequel__fallback' | 'player_prequel__fallback_end' | 'player_prequel__silence' | 'player_prequel__silence_end'; From f0cdfd1a110eccbb36cc05e9a24bd5f78c67d404 Mon Sep 17 00:00:00 2001 From: Pierre Leroux <panacpp@gmail.com> Date: Wed, 6 Apr 2022 18:15:05 +0200 Subject: [PATCH 164/180] fix: missing player_prequel.summary key in i18n --- webhooks/functions/src/translation/fr/fr.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/webhooks/functions/src/translation/fr/fr.json b/webhooks/functions/src/translation/fr/fr.json index f95deb98..c0023217 100644 --- a/webhooks/functions/src/translation/fr/fr.json +++ b/webhooks/functions/src/translation/fr/fr.json @@ -129,6 +129,9 @@ "2": "{{- resumeOrStart}}, écouter le résumé, ou revenir à la liste précédente ?", "2-continue": "Voulez-vous reprendre la lecture", "2-begin": "Voulez-vous commencer la lecture" + }, + "summary": { + "1": "Voulez-vous commencer la lecture ou revenir à la liste précédente ?" } }, "player": { From 9d5d63d10c1be0061979906fd7f74a3305d9f92c Mon Sep 17 00:00:00 2001 From: Pierre Leroux <panacpp@gmail.com> Date: Wed, 6 Apr 2022 18:25:39 +0200 Subject: [PATCH 165/180] fix: partial-fix #43 reset index and time in history when a book is finished --- webhooks/functions/src/controller/Machine.ts | 6 +++--- webhooks/functions/src/controller/handler/player.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 1dd1135b..aff89683 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -508,12 +508,12 @@ export class Machine { return size; } - public persistMediaPlayer() { + public persistMediaPlayer(finished: boolean = false) { ok(this._model); const _progress = this._conv.context?.media?.progress || '0'; - const progress = parseInt(_progress, 10); - const index = this._conv.request.context?.media?.index || 0; + const progress = finished ? 0 : parseInt(_progress, 10); + const index = finished ? 0 : (this._conv.request.context?.media?.index || 0); const url = this._model.store.player.current.url; if (!url) { return; diff --git a/webhooks/functions/src/controller/handler/player.ts b/webhooks/functions/src/controller/handler/player.ts index eae593b4..bf2b4911 100644 --- a/webhooks/functions/src/controller/handler/player.ts +++ b/webhooks/functions/src/controller/handler/player.ts @@ -39,7 +39,7 @@ const failed: THandlerFn = async (m) => { const finished: THandlerFn = async (m) => { - m.persistMediaPlayer(); + m.persistMediaPlayer(true); m.nextScene = "home_user"; }; \ No newline at end of file From 4913ab75b8a69cef6ca2d2887b10569dd82a16d2 Mon Sep 17 00:00:00 2001 From: Pierre Leroux <panacpp@gmail.com> Date: Thu, 7 Apr 2022 14:50:17 +0200 Subject: [PATCH 166/180] fix: player finished test --- webhooks/functions/src/sdk/player.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webhooks/functions/src/sdk/player.test.ts b/webhooks/functions/src/sdk/player.test.ts index aa462a8a..bfc40655 100644 --- a/webhooks/functions/src/sdk/player.test.ts +++ b/webhooks/functions/src/sdk/player.test.ts @@ -68,7 +68,7 @@ describe(scene + ' handler', () => { const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); model.data.store.player.current.index = 2; - model.data.store.player.current.time?.should.to.be.eq(40); + model.data.store.player.current.time?.should.to.be.eq(0); model.data.store.player.current.url?.should.to.be.eq('http://my.url'); }); it('media status stopped', async () => { From 7dbe37405d7c03fcb3f723626cd69b6e8e283274 Mon Sep 17 00:00:00 2001 From: Pierre Leroux <panacpp@gmail.com> Date: Thu, 7 Apr 2022 15:31:48 +0200 Subject: [PATCH 167/180] sdk: account linking handler --- sdk/custom/scenes/home_new_user_AccountLinking.yaml | 3 +-- sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/sdk/custom/scenes/home_new_user_AccountLinking.yaml b/sdk/custom/scenes/home_new_user_AccountLinking.yaml index 38550691..4772059e 100644 --- a/sdk/custom/scenes/home_new_user_AccountLinking.yaml +++ b/sdk/custom/scenes/home_new_user_AccountLinking.yaml @@ -1,7 +1,6 @@ conditionalEvents: - condition: session.params.AccountLinkingSlot == "LINKED" - handler: - webhookHandler: home_new_user_AccountLinking__linked + transitionToScene: home_user - condition: session.params.AccountLinkingSlot == "ERROR" transitionToScene: actions.scene.END_CONVERSATION - condition: session.params.AccountLinkingSlot == "REJECTED" diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index bb3bc259..5da8b1a1 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -9,7 +9,6 @@ handlers: - name: home_new_user__intent__fallback_end - name: home_new_user__intent__silence - name: home_new_user__intent__silence_end -- name: home_new_user_AccountLinking__linked - name: home_new_user_maybe_later__intent__learn_more - name: home_new_user_maybe_later__intent__repeat - name: home_new_user_maybe_later__intent__link_account From b336907f06c1c59dda842786800a3ac3e3ae5e09 Mon Sep 17 00:00:00 2001 From: Pierre Leroux <panacpp@gmail.com> Date: Fri, 8 Apr 2022 16:43:38 +0200 Subject: [PATCH 168/180] fix: set opdsPubSelfLink to history instead webpubUrl - partial fix #82 --- webhooks/functions/src/controller/Machine.ts | 95 ++++++++++--------- .../functions/src/controller/handler/index.ts | 7 +- .../src/controller/handler/player_prequel.ts | 5 - .../src/controller/handler/selection.ts | 2 + webhooks/functions/src/sdk/home_user.test.ts | 32 ++++++- .../functions/src/sdk/player_prequel.test.ts | 85 +++++++++++++++-- webhooks/functions/src/sdk/selection.test.ts | 29 ++++++ webhooks/functions/src/translation/en/en.json | 3 +- webhooks/functions/src/translation/fr/fr.json | 3 +- webhooks/functions/src/typings/i18n.d.ts | 8 +- .../functions/src/typings/sdkHandler.d.ts | 2 +- 11 files changed, 199 insertions(+), 72 deletions(-) diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index aff89683..32310f94 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -9,7 +9,7 @@ import {resetSelection} from './handler/selection.helper'; import validator from 'validator'; import {Media} from '@assistant/conversation'; import {MediaType, OptionalMediaControl} from '@assistant/conversation/dist/api/schema'; -import {IOpdsLinkView, IOpdsPublicationView, IOpdsResultView} from 'opds-fetcher-parser/build/src/interface/opds'; +import {IOpdsPublicationView, IOpdsResultView} from 'opds-fetcher-parser/build/src/interface/opds'; import {TSdkHandler} from '../typings/sdkHandler'; import {WebpubError} from '../error'; import {stall} from '../tools'; @@ -181,16 +181,21 @@ export class Machine { ok(cur); const url = cur.url || ''; const chapter = (cur.index || 0) + 1; - const {title, author, description} = await this.getInfoFromWebpub(url); + const {title, author, description} = await this.getInfoFromOpdsPub(url); return {chapter, title, author, description}; } - public async getInfoFromWebpub(url: string) { - const webpub = await this.webpubRequest(url); - const title = webpub?.title || 'no title'; // @TODO i18n - const author = (webpub?.authors || [])[0] || ''; - const description = (webpub?.description) || ''; + public async getInfoFromOpdsPub(opdsPubUrl: string) { + if (!this.isValidHttpUrl(opdsPubUrl)) { + throw new Error('not a valid opdsPubUrl in getInfoFromOpdsPub'); + } + const {publications} = await this.feedRequest(opdsPubUrl); + + const pub = Array.isArray(publications) ? publications[0] : undefined; + const title: string = pub?.title || this.t('noTitle'); + const author: string = ((pub && Array.isArray(pub?.authors)) ? pub?.authors : [])[0]?.name || ''; + const description: string = (pub?.description) || ''; return {title, author, description}; } @@ -311,7 +316,7 @@ export class Machine { let pub: { title: string; author: string; - webpubUrl: string; + opdsPubUrl: string; } | undefined; if (url.startsWith('data://')) { @@ -321,11 +326,13 @@ export class Machine { const urlFromData = data[number - 1]; if (this.isValidHttpUrl(urlFromData)) { - const webpub = await this.webpubRequest(urlFromData); + const {publications} = await this.feedRequest(urlFromData); + const publication = Array.isArray(publications) ? publications[0] : undefined; + const author: string = ((publication && Array.isArray(publication?.authors)) ? publication?.authors : [])[0]?.name || ''; pub = { - title: webpub.title, - author: webpub.authors[0] || '', - webpubUrl: urlFromData, + title: publication?.title || this.t('noTitle'), + author, + opdsPubUrl: urlFromData, }; } } else { @@ -333,11 +340,8 @@ export class Machine { } if (pub) { - const webpubUrl = pub.webpubUrl; - if (!this.isValidHttpUrl(webpubUrl)) { - throw new Error('webpub url not valid'); - } - this.initPlayerInPlayerPrequelSession(pub.webpubUrl); + const {opdsPubUrl} = pub; + this.initPlayerInPlayerPrequelSession(opdsPubUrl); return true; } @@ -352,11 +356,11 @@ export class Machine { this.selectionSession.nextUrlCounter = 0; // reset } - public initPlayerInPlayerPrequelSession(webpubUrl: string) { + public initPlayerInPlayerPrequelSession(opdsPubUrl: string) { ok(this._model); - const pubFromHistory = this._model.store.player.history.get(webpubUrl); + const pubFromHistory = this._model.store.player.history.get(opdsPubUrl); this.playerPrequelSession.player = { - url: webpubUrl, + url: opdsPubUrl, index: pubFromHistory?.index ?? 0, time: pubFromHistory?.time ?? 0, }; @@ -457,19 +461,19 @@ export class Machine { const feed = await this.feedRequest(url); const list = (feed.publications || []) - .filter(({openAccessLinks: l}) /* : l is IOpdsLinkView[]*/ => { - return ( - Array.isArray(l) && - l[0] && - this.isValidHttpUrl(l[0].url) - ); + .filter(({entryLinks: l}) => { + return Array.isArray(l) && l[0]?.url && this.isValidHttpUrl(l[0].url); + }) + .filter(({openAccessLinks: l}) => { + return Array.isArray(l) && l[0]?.url && this.isValidHttpUrl(l[0].url); }) .slice(0, PADDING_PUB) - .map(({title, authors, openAccessLinks}) => ({ + .map(({title, authors, entryLinks}) => ({ title: title, author: Array.isArray(authors) && authors.length ? authors[0].name : '', - webpubUrl: (openAccessLinks as IOpdsLinkView[])[0].url, + opdsPubUrl: entryLinks ? entryLinks[0].url : '', })); + return {publication: list, length: feed.metadata?.numberOfItems || list.length}; } @@ -550,14 +554,21 @@ export class Machine { public async player() { ok(this._model); const url = this.currentPlayingUrl; - if (!url) { - throw new Error('no playing url'); + if (!this.isValidHttpUrl(url)) { + throw new Error('no opdsPublication url'); + } + + const {publications} = await this.feedRequest(url); + const webpubUrl: string = (Array.isArray(publications) && Array.isArray(publications[0]?.openAccessLinks)) ? publications[0].openAccessLinks[0]?.url : ''; + + if (!this.isValidHttpUrl(webpubUrl)) { + throw new Error('no webpub url'); } const startIndexRaw = this._model.store.player.current.index; const startTimeRaw = this._model.store.player.current.time; - const webpub = await this.webpubRequest(url); + const webpub = await this.webpubRequest(webpubUrl); let startIndex = (startIndexRaw && startIndexRaw > -1 && startIndexRaw <= webpub.readingOrders.length) ? startIndexRaw : @@ -624,23 +635,15 @@ export class Machine { // recent books hack if (url.startsWith('data://')) { const dataStr = url.substring('data://'.length); - const data = JSON.parse(dataStr); + const data: string[] = JSON.parse(dataStr); ok(Array.isArray(data)); - const publications: IOpdsPublicationView[] = []; - for (const urlFromData of data) { - const webpub = await this._fetcher.webpubRequest(urlFromData); - const title = webpub.title || ''; - const authors = webpub.authors || []; - publications.push({ - title, - // @ts-ignore - authors: [{name: authors[0]}], - openAccessLinks: [{ - url: urlFromData, - }], - }); - } + const dataFiltered = data.filter((v) => typeof v === 'string' && this.isValidHttpUrl(v)); + const feedResultP = dataFiltered.map((url) => this._fetcher!.feedRequest(url)); + const feedResult = await Promise.all(feedResultP); + const publications = feedResult + .map(({publications}) => Array.isArray(publications) ? publications[0] : undefined) + .filter((v) => !!v) as IOpdsPublicationView[]; const feed: IOpdsResultView = { title: 'recent books', diff --git a/webhooks/functions/src/controller/handler/index.ts b/webhooks/functions/src/controller/handler/index.ts index b34ec572..9d5e2908 100644 --- a/webhooks/functions/src/controller/handler/index.ts +++ b/webhooks/functions/src/controller/handler/index.ts @@ -1,3 +1,4 @@ +import { NAME } from "../../constants"; import { Assistant } from "../Assistant"; import { collections } from "./collections"; import { home_new_user } from "./home_new_user"; @@ -18,7 +19,7 @@ export const handler = (app = new Assistant({})) => { app.handle('cancel', (m) => { m.persistMediaPlayer(); - m.say('bye.1'); + m.say('bye.1', {name: NAME}); }); app.handle('fallback_1', (m) => { @@ -32,7 +33,7 @@ export const handler = (app = new Assistant({})) => { app.handle('fallback_end', (m) => { m.persistMediaPlayer(); - m.say('bye.1'); + m.say('bye.1', {name: NAME}); }); app.handle('silence_1', (m) => { @@ -46,7 +47,7 @@ export const handler = (app = new Assistant({})) => { app.handle('silence_end', (m) => { m.persistMediaPlayer(); - m.say('bye.1'); + m.say('bye.1', {name: NAME}); }); home_user(app); diff --git a/webhooks/functions/src/controller/handler/player_prequel.ts b/webhooks/functions/src/controller/handler/player_prequel.ts index 70d872eb..4c0d0a36 100644 --- a/webhooks/functions/src/controller/handler/player_prequel.ts +++ b/webhooks/functions/src/controller/handler/player_prequel.ts @@ -24,13 +24,8 @@ const enter: THandlerFn = async (m) => { const from = m.playerPrequelSession.from; // const fromScene = from.split("__")[0] as TSdkScene; - - // const state = m.getSessionState('player_prequel'); - console.log(from); - - if (from === "home_user__intent__current_book") { // from home user last book diff --git a/webhooks/functions/src/controller/handler/selection.ts b/webhooks/functions/src/controller/handler/selection.ts index a8d40972..12df49a8 100644 --- a/webhooks/functions/src/controller/handler/selection.ts +++ b/webhooks/functions/src/controller/handler/selection.ts @@ -157,10 +157,12 @@ const selectBook: THandlerFn = async (m) => { } else if (nb < 1) { m.selectionSession.nbChoice = 0; + console.info("number from intent lower than 1"); // m.say('selection.help.1'); } else if (nb > padding || nb > size) { m.selectionSession.nbChoice = 0; + console.info("number from intent upper than padding or size"); // m.say('selection.help.1'); } else { diff --git a/webhooks/functions/src/sdk/home_user.test.ts b/webhooks/functions/src/sdk/home_user.test.ts index 7ddad13f..6663998f 100644 --- a/webhooks/functions/src/sdk/home_user.test.ts +++ b/webhooks/functions/src/sdk/home_user.test.ts @@ -124,6 +124,20 @@ describe('home_user handler', () => { pullData.player.current.url = 'https://my.url'; pullData.player.current.time = 0; + const feed: Partial<any> = { + publications: [ + { + entryLinks: [{url: 'http://self.link'}], + openAccessLinks: [{url: 'http://webpub.link'}], + title: 'my title', + authors: [ + { + name: 'hello', + }, + ], + }, + ], + }; const webpub: Partial<IWebPubView> = { title: 'my title', authors: [ @@ -132,7 +146,7 @@ describe('home_user handler', () => { ], }; - const data = await expressMocked(body, headers, pullData, undefined, webpub); + const data = await expressMocked(body, headers, pullData, feed, webpub); console.log(JSON.stringify(data, null, 4)); data.prompt.firstSimple.speech.should.to.be.eq('You are listening to the 10 chapter of my title, hello, which you can now pick up.\n' + @@ -162,6 +176,20 @@ describe('home_user handler', () => { // pullData.player.history.set("3", {index: 0, time: 0, date: new Date()}); // pullData.player.history.set("4", {index: 0, time: 0, date: new Date()}); + const feed: Partial<any> = { + publications: [ + { + entryLinks: [{url: 'http://self.link'}], + openAccessLinks: [{url: 'http://webpub.link'}], + title: 'my title', + authors: [ + { + name: 'hello', + }, + ], + }, + ], + }; const webpub: Partial<IWebPubView> = { title: 'my title', authors: [ @@ -170,7 +198,7 @@ describe('home_user handler', () => { ], }; - const data = await expressMocked(body, headers, pullData, undefined, webpub); + const data = await expressMocked(body, headers, pullData, feed, webpub); console.log(JSON.stringify(data, null, 4)); data.prompt.firstSimple.speech.should.to.be.eq('You are listening to the 10 chapter of my title, hello, which you can now pick up.\n' + diff --git a/webhooks/functions/src/sdk/player_prequel.test.ts b/webhooks/functions/src/sdk/player_prequel.test.ts index e67f303f..8c9cc5e6 100644 --- a/webhooks/functions/src/sdk/player_prequel.test.ts +++ b/webhooks/functions/src/sdk/player_prequel.test.ts @@ -84,6 +84,16 @@ describe(scene + ' handler', () => { pullData.player.current.time = 0; pullData.player.current.url = 'http://my.url'; + const feed: Partial<any> = { + publications: [ + { + entryLinks: [{url: 'http://self.link'}], + openAccessLinks: [{url: 'http://webpub.link'}], + title: 'my title', + }, + ], + }; + const webpub: Partial<IWebPubView> = { title: 'my title', authors: [ @@ -95,7 +105,7 @@ describe(scene + ' handler', () => { pullData.session.scene.player_prequel.from = 'home_user__intent__current_book'; const model = await storageModelMocked(pullData); - const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); + const data = await expressMocked(body, headers, undefined, feed, webpub, model.data); data.scene.next.name.should.to.be.eq('player'); @@ -113,6 +123,15 @@ describe(scene + ' handler', () => { pullData.session.scene.player_prequel.player.url = 'https://my.url'; pullData.session.scene.player_prequel.from = 'selection__on_enter'; + const feed: Partial<any> = { + publications: [ + { + entryLinks: [{url: 'http://self.link'}], + openAccessLinks: [{url: 'http://webpub.link'}], + title: 'my title', + }, + ], + }; const webpub: Partial<IWebPubView> = { title: 'my title', authors: [ @@ -122,7 +141,7 @@ describe(scene + ' handler', () => { }; const model = await storageModelMocked(pullData); - const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); + const data = await expressMocked(body, headers, undefined, feed, webpub, model.data); (typeof model.data.store.player.current.index).should.be.eq('undefined'); (typeof model.data.store.player.current.time).should.be.eq('undefined'); @@ -146,6 +165,17 @@ describe(scene + ' handler', () => { pullData.session.scene.player_prequel.player.url = 'https://my.url'; pullData.session.scene.player_prequel.from = 'selection__on_enter'; + + + const feed: Partial<any> = { + publications: [ + { + entryLinks: [{url: 'http://self.link'}], + openAccessLinks: [{url: 'http://webpub.link'}], + title: 'my title', + }, + ], + }; const webpub: Partial<IWebPubView> = { title: 'my title', authors: [ @@ -155,7 +185,7 @@ describe(scene + ' handler', () => { }; const model = await storageModelMocked(pullData); - const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); + const data = await expressMocked(body, headers, undefined, feed, webpub, model.data); (typeof model.data.store.player.current.index).should.be.eq('undefined'); (typeof model.data.store.player.current.time).should.be.eq('undefined'); @@ -183,6 +213,15 @@ describe(scene + ' handler', () => { pullData.session.scene.player_prequel.player.url = 'https://my.url'; pullData.session.scene.player_prequel.from = 'selection__on_enter'; + const feed: Partial<any> = { + publications: [ + { + entryLinks: [{url: 'http://self.link'}], + openAccessLinks: [{url: 'http://webpub.link'}], + title: 'my title', + }, + ], + }; const webpub: Partial<IWebPubView> = { title: 'my title', authors: [ @@ -192,7 +231,7 @@ describe(scene + ' handler', () => { }; const model = await storageModelMocked(pullData); - const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); + const data = await expressMocked(body, headers, undefined, feed, webpub, model.data); (typeof model.data.store.session.scene.player_prequel.player.index).should.be.eq('undefined'); (typeof model.data.store.session.scene.player_prequel.player.time).should.be.eq('undefined'); @@ -212,6 +251,16 @@ describe(scene + ' handler', () => { pullData.session.scene.player_prequel.player.url = 'https://my.url'; pullData.session.scene.player_prequel.from = 'selection__on_enter'; + const feed: Partial<any> = { + publications: [ + { + entryLinks: [{url: 'http://self.link'}], + openAccessLinks: [{url: 'http://webpub.link'}], + title: 'my title', + + }, + ], + }; const webpub: Partial<IWebPubView> = { title: 'my title', authors: [ @@ -221,7 +270,7 @@ describe(scene + ' handler', () => { }; const model = await storageModelMocked(pullData); - const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); + const data = await expressMocked(body, headers, undefined, feed, webpub, model.data); (typeof model.data.store.session.scene.player_prequel.player.index).should.be.eq('undefined'); (typeof model.data.store.session.scene.player_prequel.player.time).should.be.eq('undefined'); @@ -250,6 +299,15 @@ describe(scene + ' handler', () => { pullData.session.scene.player_prequel.player.url = 'https://my.url'; pullData.session.scene.player_prequel.from = 'selection__on_enter'; + const feed: Partial<any> = { + publications: [ + { + entryLinks: [{url: 'http://self.link'}], + openAccessLinks: [{url: 'http://webpub.link'}], + title: 'my title', + }, + ], + }; const webpub: Partial<IWebPubView> = { title: 'my title', authors: [ @@ -259,7 +317,7 @@ describe(scene + ' handler', () => { }; const model = await storageModelMocked(pullData); - const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); + const data = await expressMocked(body, headers, undefined, feed, webpub, model.data); (typeof model.data.store.session.scene.player_prequel.player.index).should.be.eq('undefined'); (typeof model.data.store.session.scene.player_prequel.player.time).should.be.eq('undefined'); @@ -288,19 +346,28 @@ describe(scene + ' handler', () => { pullData.session.scene.player_prequel.player.url = 'https://my.url'; pullData.session.scene.player_prequel.from = 'selection__on_enter'; + const feed: Partial<any> = { + publications: [ + { + entryLinks: [{url: 'http://self.link'}], + openAccessLinks: [{url: 'http://webpub.link'}], + description: 'this is the world in feed', + }, + ], + }; const webpub: Partial<IWebPubView> = { title: 'my title', authors: [ 'hello', 'world', ], - description: 'this the world', + description: 'this is the world', }; const model = await storageModelMocked(pullData); - const data = await expressMocked(body, headers, undefined, undefined, webpub, model.data); + const data = await expressMocked(body, headers, undefined, feed, webpub, model.data); - data.prompt.firstSimple.speech.should.to.be.eq('Here is the summary: this the world.\nDo you want to start reading or go back to the list?\n'); + data.prompt.firstSimple.speech.should.to.be.eq('Here is the summary: this is the world in feed.\nDo you want to start reading or go back to the list?\n'); }); }); }); diff --git a/webhooks/functions/src/sdk/selection.test.ts b/webhooks/functions/src/sdk/selection.test.ts index 7421621c..4898b84f 100644 --- a/webhooks/functions/src/sdk/selection.test.ts +++ b/webhooks/functions/src/sdk/selection.test.ts @@ -143,6 +143,11 @@ describe(scene + ' handler', () => { url: 'http://pub.url', }, ], + entryLinks: [ + { + url: 'http://self.url', + }, + ], baseUrl: 'http://base.url', title: 'first publication', authors: [], @@ -154,6 +159,11 @@ describe(scene + ' handler', () => { url: 'http://pub.url', }, ], + entryLinks: [ + { + url: 'http://self.url', + }, + ], baseUrl: 'http://base.url', title: 'second publication', authors: [], @@ -199,6 +209,11 @@ describe(scene + ' handler', () => { const feed: Partial<IOpdsResultView> = { publications: [ { + entryLinks: [ + { + url: 'http://webpub.url', + }, + ], openAccessLinks: [ { url: 'http://pub.url', @@ -210,6 +225,11 @@ describe(scene + ' handler', () => { numberOfPages: 0, }, { + entryLinks: [ + { + url: 'http://webpub.url', + }, + ], openAccessLinks: [ { url: 'http://pub.url', @@ -221,6 +241,11 @@ describe(scene + ' handler', () => { numberOfPages: 0, }, { + entryLinks: [ + { + url: 'http://webpub.url', + }, + ], openAccessLinks: [ { url: 'http://pub.url', @@ -472,6 +497,10 @@ describe(scene + ' handler', () => { pullData.session.scene.selection.url = 'data://["https://my.url","https://my.url","https://my.url"]'; pullData.session.scene.selection.from = 'home_user__intent__recent_books'; + // @ts-ignore + feed.publications[0].title = 'my test title'; + + // USELESS NOW ! const webpub: Partial<IWebPubView> = { title: 'my test title', authors: ['author'], diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index 4003be8c..059b2f6f 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -161,5 +161,6 @@ }, "error": { "1": "Oops, something went wrong. I will send you back to the home menu." - } + }, + "noTitle": "No title available" } diff --git a/webhooks/functions/src/translation/fr/fr.json b/webhooks/functions/src/translation/fr/fr.json index c0023217..5adfa300 100644 --- a/webhooks/functions/src/translation/fr/fr.json +++ b/webhooks/functions/src/translation/fr/fr.json @@ -161,5 +161,6 @@ }, "error": { "1": "Oups, quelque chose s'est mal passé. Je vous renvoie au menu d'accueil." - } + }, + "noTitle": "Aucun titre disponible" } diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index a971106e..e1fc5776 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.enter.regular.2" | "home_user.currentBook.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "player_prequel.summarize" | "player_prequel.noSummary" | "player_prequel.help.1" | "player_prequel.enter.1" | "player_prequel.enter.2" | "player_prequel.enter.1-continue" | "player_prequel.enter.1-begin" | "player_prequel.enter.2-continue" | "player_prequel.enter.2-begin" | "player_prequel.summary.1" | "player_prequel.summary.1-continue" | "player_prequel.summary.1-begin" | "player.explain" | "player.start" | "player.start2" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1", - "fr": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.enter.regular.2" | "home_user.currentBook.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "player_prequel.summarize" | "player_prequel.noSummary" | "player_prequel.help.1" | "player_prequel.enter.1" | "player_prequel.enter.2" | "player_prequel.enter.1-continue" | "player_prequel.enter.1-begin" | "player_prequel.enter.2-continue" | "player_prequel.enter.2-begin" | "player.explain" | "player.start" | "player.start2" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1" + "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.currentBook.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "player_prequel.summarize" | "player_prequel.noSummary" | "player_prequel.help.1" | "player_prequel.enter.1" | "player_prequel.enter.2" | "player_prequel.enter.1-continue" | "player_prequel.enter.1-begin" | "player_prequel.enter.2-continue" | "player_prequel.enter.2-begin" | "player_prequel.summary.1" | "player.explain" | "player.start" | "player.start2" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1" | "noTitle", + "fr": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.currentBook.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "player_prequel.summarize" | "player_prequel.noSummary" | "player_prequel.help.1" | "player_prequel.enter.1" | "player_prequel.enter.2" | "player_prequel.enter.1-continue" | "player_prequel.enter.1-begin" | "player_prequel.enter.2-continue" | "player_prequel.enter.2-begin" | "player_prequel.summary.1" | "player.explain" | "player.start" | "player.start2" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1" | "noTitle" }; keysWithNS: { - "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.enter.regular.2" | "en:home_user.currentBook.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:search.enter.2" | "en:search.empty.1" | "en:search.empty.2" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.nextPage.1" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:player_prequel.summarize" | "en:player_prequel.noSummary" | "en:player_prequel.help.1" | "en:player_prequel.enter.1" | "en:player_prequel.enter.2" | "en:player_prequel.enter.1-continue" | "en:player_prequel.enter.1-begin" | "en:player_prequel.enter.2-continue" | "en:player_prequel.enter.2-begin" | "en:player_prequel.summary.1" | "en:player_prequel.summary.1-continue" | "en:player_prequel.summary.1-begin" | "en:player.explain" | "en:player.start" | "en:player.start2" | "en:collections.enter.1" | "en:collections.help.1" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1", - "fr": "fr:main.welcome.noLinked.1" | "fr:main.welcome.linked.1" | "fr:home_new_user.enter.first.1" | "fr:home_new_user.enter.first.2" | "fr:home_new_user.no.1" | "fr:home_new_user.no.2" | "fr:home_new_user.help.1" | "fr:home_new_user.help.2" | "fr:home_new_user.maybeLater.1" | "fr:home_new_user.maybeLater.2" | "fr:home_new_user_maybe_later.help.1" | "fr:home_new_user_no.help.1" | "fr:info.about.1" | "fr:info.help.1" | "fr:info.yesOrMembership.1" | "fr:home_user.enter.newlyUser.1" | "fr:home_user.enter.newlyUser.2" | "fr:home_user.enter.playing.1" | "fr:home_user.enter.playing.2" | "fr:home_user.enter.playing.3" | "fr:home_user.enter.regular.1" | "fr:home_user.enter.regular.2" | "fr:home_user.currentBook.1" | "fr:home_user.help.1" | "fr:home_user.help.2" | "fr:search.enter.1" | "fr:search.enter.2" | "fr:search.empty.1" | "fr:search.empty.2" | "fr:selection.enter.bookshelf.first" | "fr:selection.enter.bookshelf.second" | "fr:selection.enter.search" | "fr:selection.enter.collection.publication" | "fr:selection.enter.collection.group" | "fr:selection.enter.lastPage.publication" | "fr:selection.enter.lastPage.group" | "fr:selection.enter.lastPage.notAvailable" | "fr:selection.enter.common.1" | "fr:selection.enter.common.2" | "fr:selection.enter.common.3" | "fr:selection.enter.nextPage.1" | "fr:selection.enter.empty.1" | "fr:selection.help.1" | "fr:player_prequel.summarize" | "fr:player_prequel.noSummary" | "fr:player_prequel.help.1" | "fr:player_prequel.enter.1" | "fr:player_prequel.enter.2" | "fr:player_prequel.enter.1-continue" | "fr:player_prequel.enter.1-begin" | "fr:player_prequel.enter.2-continue" | "fr:player_prequel.enter.2-begin" | "fr:player.explain" | "fr:player.start" | "fr:player.start2" | "fr:collections.enter.1" | "fr:collections.help.1" | "fr:void" | "fr:bye.1" | "fr:fallback.1" | "fr:fallback.2" | "fr:silence.1" | "fr:silence.2" | "fr:error.1" + "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.currentBook.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:search.enter.2" | "en:search.empty.1" | "en:search.empty.2" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.nextPage.1" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:player_prequel.summarize" | "en:player_prequel.noSummary" | "en:player_prequel.help.1" | "en:player_prequel.enter.1" | "en:player_prequel.enter.2" | "en:player_prequel.enter.1-continue" | "en:player_prequel.enter.1-begin" | "en:player_prequel.enter.2-continue" | "en:player_prequel.enter.2-begin" | "en:player_prequel.summary.1" | "en:player.explain" | "en:player.start" | "en:player.start2" | "en:collections.enter.1" | "en:collections.help.1" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1" | "en:noTitle", + "fr": "fr:main.welcome.noLinked.1" | "fr:main.welcome.linked.1" | "fr:home_new_user.enter.first.1" | "fr:home_new_user.enter.first.2" | "fr:home_new_user.no.1" | "fr:home_new_user.no.2" | "fr:home_new_user.help.1" | "fr:home_new_user.help.2" | "fr:home_new_user.maybeLater.1" | "fr:home_new_user.maybeLater.2" | "fr:home_new_user_maybe_later.help.1" | "fr:home_new_user_no.help.1" | "fr:info.about.1" | "fr:info.help.1" | "fr:info.yesOrMembership.1" | "fr:home_user.enter.newlyUser.1" | "fr:home_user.enter.newlyUser.2" | "fr:home_user.enter.playing.1" | "fr:home_user.enter.playing.2" | "fr:home_user.enter.playing.3" | "fr:home_user.enter.regular.1" | "fr:home_user.currentBook.1" | "fr:home_user.help.1" | "fr:home_user.help.2" | "fr:search.enter.1" | "fr:search.enter.2" | "fr:search.empty.1" | "fr:search.empty.2" | "fr:selection.enter.bookshelf.first" | "fr:selection.enter.bookshelf.second" | "fr:selection.enter.search" | "fr:selection.enter.collection.publication" | "fr:selection.enter.collection.group" | "fr:selection.enter.lastPage.publication" | "fr:selection.enter.lastPage.group" | "fr:selection.enter.lastPage.notAvailable" | "fr:selection.enter.common.1" | "fr:selection.enter.common.2" | "fr:selection.enter.common.3" | "fr:selection.enter.nextPage.1" | "fr:selection.enter.empty.1" | "fr:selection.help.1" | "fr:player_prequel.summarize" | "fr:player_prequel.noSummary" | "fr:player_prequel.help.1" | "fr:player_prequel.enter.1" | "fr:player_prequel.enter.2" | "fr:player_prequel.enter.1-continue" | "fr:player_prequel.enter.1-begin" | "fr:player_prequel.enter.2-continue" | "fr:player_prequel.enter.2-begin" | "fr:player_prequel.summary.1" | "fr:player.explain" | "fr:player.start" | "fr:player.start2" | "fr:collections.enter.1" | "fr:collections.help.1" | "fr:void" | "fr:bye.1" | "fr:fallback.1" | "fr:fallback.2" | "fr:silence.1" | "fr:silence.2" | "fr:error.1" | "fr:noTitle" }; } diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index 81e85714..12fd2aed 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_AccountLinking__linked' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end' | 'player__on_enter' | 'player__intent__media_status_finished' | 'player__intent__media_status_paused' | 'player__intent__media_status_stopped' | 'player__intent__media_status_failed' | 'search__on_enter' | 'search__intent__search_query' | 'search__intent__search' | 'collections__on_enter' | 'collections__intent__bookshelf' | 'collections__intent__by_genre' | 'collections__intent__by_theme' | 'collections__intent__help' | 'collections__intent__fallback' | 'collections__intent__fallback_end' | 'collections__intent__silence' | 'collections__intent__silence_end' | 'player_prequel__on_enter' | 'home_user__intent__recent_books' | 'info__intent__no' | 'home_user__intent__current_book' | 'player_prequel__intent__help' | 'player_prequel__intent__repeat' | 'player_prequel__intent__player_prequel_back' | 'player_prequel__intent__player_prequel_resume' | 'player_prequel__intent__player_prequel_start' | 'player_prequel__intent__player_prequel_summary' | 'player_prequel__fallback' | 'player_prequel__fallback_end' | 'player_prequel__silence' | 'player_prequel__silence_end'; +export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end' | 'player__on_enter' | 'player__intent__media_status_finished' | 'player__intent__media_status_paused' | 'player__intent__media_status_stopped' | 'player__intent__media_status_failed' | 'search__on_enter' | 'search__intent__search_query' | 'search__intent__search' | 'collections__on_enter' | 'collections__intent__bookshelf' | 'collections__intent__by_genre' | 'collections__intent__by_theme' | 'collections__intent__help' | 'collections__intent__fallback' | 'collections__intent__fallback_end' | 'collections__intent__silence' | 'collections__intent__silence_end' | 'player_prequel__on_enter' | 'home_user__intent__recent_books' | 'info__intent__no' | 'home_user__intent__current_book' | 'player_prequel__intent__help' | 'player_prequel__intent__repeat' | 'player_prequel__intent__player_prequel_back' | 'player_prequel__intent__player_prequel_resume' | 'player_prequel__intent__player_prequel_start' | 'player_prequel__intent__player_prequel_summary' | 'player_prequel__fallback' | 'player_prequel__fallback_end' | 'player_prequel__silence' | 'player_prequel__silence_end'; From b6b7ac290660450b46f5d4bb76ea16d91226bad1 Mon Sep 17 00:00:00 2001 From: Pierre Leroux <panacpp@gmail.com> Date: Fri, 8 Apr 2022 16:57:13 +0200 Subject: [PATCH 169/180] sdk: add lecture to prequel_resume --- sdk/custom/intents/player_prequel_resume.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/custom/intents/player_prequel_resume.yaml b/sdk/custom/intents/player_prequel_resume.yaml index 844e462f..1afd7524 100644 --- a/sdk/custom/intents/player_prequel_resume.yaml +++ b/sdk/custom/intents/player_prequel_resume.yaml @@ -1,2 +1,3 @@ trainingPhrases: +- lecture - Reprendre la lecture From 844ceb0025d1a534e3dc577b9c00f427cf31a1b7 Mon Sep 17 00:00:00 2001 From: Pierre Leroux <panacpp@gmail.com> Date: Fri, 8 Apr 2022 17:37:17 +0200 Subject: [PATCH 170/180] fix: set 3 items max in recent_books --- webhooks/functions/src/controller/Machine.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 32310f94..b19cf340 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -638,7 +638,9 @@ export class Machine { const data: string[] = JSON.parse(dataStr); ok(Array.isArray(data)); - const dataFiltered = data.filter((v) => typeof v === 'string' && this.isValidHttpUrl(v)); + const dataFiltered = data + .filter((v) => typeof v === 'string' && this.isValidHttpUrl(v)) + .slice(0, PADDING_PUB); // FIXME: Little Hacky : need to add pagination instead of slicing 3 items const feedResultP = dataFiltered.map((url) => this._fetcher!.feedRequest(url)); const feedResult = await Promise.all(feedResultP); const publications = feedResult From 6c3bd867738f52735e1b4effa293b4686ded4808 Mon Sep 17 00:00:00 2001 From: Pierre Leroux <panacpp@gmail.com> Date: Mon, 11 Apr 2022 17:25:16 +0200 Subject: [PATCH 171/180] sdk: by theme --- sdk/custom/intents/by_theme.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdk/custom/intents/by_theme.yaml b/sdk/custom/intents/by_theme.yaml index f2725a2c..1f2b18b9 100644 --- a/sdk/custom/intents/by_theme.yaml +++ b/sdk/custom/intents/by_theme.yaml @@ -1,4 +1,6 @@ trainingPhrases: +- je veux par thème +- je t'aime - par thème - thème - je préfère par thème From f9ec9a03fc85a2f9cd854213e5316ffd53467eff Mon Sep 17 00:00:00 2001 From: Pierre Leroux <panacpp@gmail.com> Date: Mon, 11 Apr 2022 17:25:33 +0200 Subject: [PATCH 172/180] sdk: resume --- sdk/custom/intents/en/player_prequel_resume.yaml | 5 +++++ sdk/custom/intents/player_prequel_resume.yaml | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/sdk/custom/intents/en/player_prequel_resume.yaml b/sdk/custom/intents/en/player_prequel_resume.yaml index 97220511..0e882540 100644 --- a/sdk/custom/intents/en/player_prequel_resume.yaml +++ b/sdk/custom/intents/en/player_prequel_resume.yaml @@ -1,2 +1,7 @@ trainingPhrases: +- continue reading +- continue playing +- continue +- Resume playback +- Resume - resume reading diff --git a/sdk/custom/intents/player_prequel_resume.yaml b/sdk/custom/intents/player_prequel_resume.yaml index 1afd7524..ba4d8cf1 100644 --- a/sdk/custom/intents/player_prequel_resume.yaml +++ b/sdk/custom/intents/player_prequel_resume.yaml @@ -1,3 +1,8 @@ trainingPhrases: +- Reprends +- Reprends la lecture +- Reprendre ma lecture +- relancer la lecture +- reprendre la lecture - lecture - Reprendre la lecture From e3125aecd966db2798fc6753ea5408a8e5637140 Mon Sep 17 00:00:00 2001 From: Pierre Leroux <panacpp@gmail.com> Date: Mon, 11 Apr 2022 17:42:43 +0200 Subject: [PATCH 173/180] fix: player issues --- sdk/custom/scenes/player.yaml | 3 +++ sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 1 + webhooks/functions/src/controller/Machine.ts | 16 +++++++++++----- .../src/controller/handler/home_user.ts | 2 +- .../functions/src/controller/handler/index.ts | 4 ++++ .../functions/src/controller/handler/player.ts | 4 ++++ .../src/controller/handler/player_prequel.ts | 9 +++++---- .../src/controller/handler/selection.ts | 4 ++-- webhooks/functions/src/sdk/conv.test.ts | 4 ++-- webhooks/functions/src/sdk/player.test.ts | 3 +++ .../functions/src/sdk/player_prequel.test.ts | 2 +- webhooks/functions/src/sdk/selection.test.ts | 6 +++--- webhooks/functions/src/typings/i18n.d.ts | 8 ++++---- webhooks/functions/src/typings/sdkHandler.d.ts | 2 +- 14 files changed, 45 insertions(+), 23 deletions(-) diff --git a/sdk/custom/scenes/player.yaml b/sdk/custom/scenes/player.yaml index e9c731a7..7b39989b 100644 --- a/sdk/custom/scenes/player.yaml +++ b/sdk/custom/scenes/player.yaml @@ -1,4 +1,7 @@ intentEvents: +- handler: + webhookHandler: player__intent__player_prequel_resume + intent: player_prequel_resume - handler: webhookHandler: player__intent__media_status_finished intent: actions.intent.MEDIA_STATUS_FINISHED diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index 5da8b1a1..66923e65 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -93,6 +93,7 @@ handlers: - name: player_prequel__fallback_end - name: player_prequel__silence - name: player_prequel__silence_end +- name: player__intent__player_prequel_resume httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index b19cf340..26de3d10 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -251,6 +251,10 @@ export class Machine { return true; } + public isPlayingAvailableInPlayer() { + return !!this.playerCurrent.url; + } + public isPlayingAvailableInPlayerPrequelSession() { return !!this.playerPrequelSession.player.url; } @@ -513,16 +517,16 @@ export class Machine { } public persistMediaPlayer(finished: boolean = false) { - ok(this._model); + if (!this._conv.request.context?.media) { + return; + } + ok(this._model); const _progress = this._conv.context?.media?.progress || '0'; const progress = finished ? 0 : parseInt(_progress, 10); const index = finished ? 0 : (this._conv.request.context?.media?.index || 0); const url = this._model.store.player.current.url; - if (!url) { - return; - } - if (!validator.isURL(url)) { + if (!this.isValidHttpUrl(url)) { return; } @@ -534,6 +538,8 @@ export class Machine { time: progress, date: new Date(), }); + + console.info(`PERSIST MEDIA PLAYER - URL= ${url}, T=${progress}, I=${index}`); } public mediaPlayerAck() { diff --git a/webhooks/functions/src/controller/handler/home_user.ts b/webhooks/functions/src/controller/handler/home_user.ts index 4ab3366d..4532a0a5 100644 --- a/webhooks/functions/src/controller/handler/home_user.ts +++ b/webhooks/functions/src/controller/handler/home_user.ts @@ -24,7 +24,7 @@ const enter: THandlerFn = async (m) => { const state = m.getSessionState("home_user"); const newlyLinked = m.authenticationState === "NEWLY_LINKED"; - const playing = m.isCurrentlyPlaying(); + const playing = m.isPlayingAvailableInPlayer(); const regularUser = m.isARegularUser; if (state === "SESSION") { diff --git a/webhooks/functions/src/controller/handler/index.ts b/webhooks/functions/src/controller/handler/index.ts index 9d5e2908..18547590 100644 --- a/webhooks/functions/src/controller/handler/index.ts +++ b/webhooks/functions/src/controller/handler/index.ts @@ -23,6 +23,8 @@ export const handler = (app = new Assistant({})) => { }); app.handle('fallback_1', (m) => { + + m.persistMediaPlayer(); m.say('fallback.1'); }); @@ -37,6 +39,8 @@ export const handler = (app = new Assistant({})) => { }); app.handle('silence_1', (m) => { + + m.persistMediaPlayer(); m.say('silence.1'); }); diff --git a/webhooks/functions/src/controller/handler/player.ts b/webhooks/functions/src/controller/handler/player.ts index bf2b4911..4f85535e 100644 --- a/webhooks/functions/src/controller/handler/player.ts +++ b/webhooks/functions/src/controller/handler/player.ts @@ -8,6 +8,7 @@ export const player = (app: Assistant) => { app.handle("player__intent__media_status_finished", finished); app.handle("player__intent__media_status_paused", paused); app.handle("player__intent__media_status_failed", failed); + app.handle("player__intent__player_prequel_resume", resume); } @@ -36,6 +37,9 @@ const failed: THandlerFn = async (m) => { m.nextScene = "home_user"; } +const resume: THandlerFn = async (m) => { + await m.player(); +} const finished: THandlerFn = async (m) => { diff --git a/webhooks/functions/src/controller/handler/player_prequel.ts b/webhooks/functions/src/controller/handler/player_prequel.ts index 4c0d0a36..c5212bda 100644 --- a/webhooks/functions/src/controller/handler/player_prequel.ts +++ b/webhooks/functions/src/controller/handler/player_prequel.ts @@ -39,7 +39,7 @@ const enter: THandlerFn = async (m) => { if (isPlayingAvailable) { m.playerPrequelSession.from = "main"; - await startPlaying(true)(m); + await startPlaying(m); return ; } } @@ -70,7 +70,7 @@ const enter: THandlerFn = async (m) => { // demandé qui l'as écrit, obtenir le temps d'écoute du livre, // ou tout simplement naviguer dans la table des matiere. -const startPlaying = (resume: boolean) => async (m: TMachine) => { +const startPlaying = async (m: TMachine) => { const isRegular = m.isARegularUser; if (!isRegular) { @@ -79,6 +79,7 @@ const startPlaying = (resume: boolean) => async (m: TMachine) => { m.initPlayerCurrentWithPlayerPrequelSession(); const { title } = await m.getCurrentPlayingInfo(); + const resume = m.isCurrentlyPlaying(); if (resume) { m.say("player.start2", { title }); } else { @@ -100,12 +101,12 @@ const back: THandlerFn = async (m) => { const resume: THandlerFn = async (m) => { - await startPlaying(true)(m); + await startPlaying(m); }; const start: THandlerFn = async (m) => { - await startPlaying(false)(m); + await startPlaying(m); }; const repeat: THandlerFn = async (m) => { diff --git a/webhooks/functions/src/controller/handler/selection.ts b/webhooks/functions/src/controller/handler/selection.ts index 12df49a8..982099e3 100644 --- a/webhooks/functions/src/controller/handler/selection.ts +++ b/webhooks/functions/src/controller/handler/selection.ts @@ -120,7 +120,7 @@ export const enter: THandlerFn = async (m) => { // KO // help message m.say("selection.help.1"); - m.nextScene = "selection"; + // m.nextScene = "selection"; } } else { throw new Error("undefined selection state"); @@ -203,7 +203,7 @@ const help: THandlerFn = (m) => { m.say("selection.help.1"); // m.say("selection.help.2"); - m.nextScene = "selection"; + // m.nextScene = "selection"; } const repeat: THandlerFn = (m) => { diff --git a/webhooks/functions/src/sdk/conv.test.ts b/webhooks/functions/src/sdk/conv.test.ts index a0adcdb5..823cc348 100644 --- a/webhooks/functions/src/sdk/conv.test.ts +++ b/webhooks/functions/src/sdk/conv.test.ts @@ -46,7 +46,7 @@ const bodyCopy = () => Object.assign({}, { 'params': { 'bearerToken': '', }, - 'accountLinkingStatus': 'ACCOUNT_LINKING_STATUS_UNSPECIFIED', + 'accountLinkingStatus': 'LINKED', 'verificationStatus': 'VERIFIED', 'packageEntitlements': [], 'gaiamint': '', @@ -103,7 +103,7 @@ export const convRequestInHandle = { 'params': { 'bearerToken': 'bearer token not defined', }, - 'accountLinkingStatus': 'ACCOUNT_LINKING_STATUS_UNSPECIFIED', + 'accountLinkingStatus': 'LINKED', 'verificationStatus': 'VERIFIED', 'packageEntitlements': [], 'gaiamint': '', diff --git a/webhooks/functions/src/sdk/player.test.ts b/webhooks/functions/src/sdk/player.test.ts index bfc40655..9a908215 100644 --- a/webhooks/functions/src/sdk/player.test.ts +++ b/webhooks/functions/src/sdk/player.test.ts @@ -11,6 +11,9 @@ chai.should(); const scene = 'player'; const yaml = `intentEvents: +- handler: + webhookHandler: player__intent__player_prequel_resume + intent: player_prequel_resume - handler: webhookHandler: player__intent__media_status_finished intent: actions.intent.MEDIA_STATUS_FINISHED diff --git a/webhooks/functions/src/sdk/player_prequel.test.ts b/webhooks/functions/src/sdk/player_prequel.test.ts index 8c9cc5e6..19f5dcb3 100644 --- a/webhooks/functions/src/sdk/player_prequel.test.ts +++ b/webhooks/functions/src/sdk/player_prequel.test.ts @@ -334,7 +334,7 @@ describe(scene + ' handler', () => { data.scene.next.name.should.to.be.eq('player'); data.prompt.firstSimple.speech.should.to.be.eq('Great choice! Before we start, let me remind you how this reader works. You can put your read on hold at any time by saying \'Hey Google, Pause\'. \'Hey Google, Resume\' will let you pick up your reading where you last left it. You can also navigate between chapters by saying \'Hey Google, next\' or \'Hey Google, previous\' at any time.\n' + - 'Let\'s start reading my title.\n'); + 'Let\'s continue reading my title.\n'); }); it('summary', async () => { body.handler.name = 'player_prequel__intent__player_prequel_summary'; diff --git a/webhooks/functions/src/sdk/selection.test.ts b/webhooks/functions/src/sdk/selection.test.ts index 4898b84f..7e8363b2 100644 --- a/webhooks/functions/src/sdk/selection.test.ts +++ b/webhooks/functions/src/sdk/selection.test.ts @@ -1075,7 +1075,7 @@ describe(scene + ' handler', () => { data.prompt.firstSimple.speech.should.to.be.eq(help); - data.scene.next.name.should.to.be.eq('selection'); + // data.scene.next.name.should.to.be.eq('selection'); }); it('fallback 1 and 2', async () => { @@ -1086,7 +1086,7 @@ describe(scene + ' handler', () => { data.prompt.firstSimple.speech.should.to.be.eq(help); - data.scene.next.name.should.to.be.eq('selection'); + // data.scene.next.name.should.to.be.eq('selection'); }); it('fallback 3', async () => { @@ -1108,7 +1108,7 @@ describe(scene + ' handler', () => { data.prompt.firstSimple.speech.should.to.be.eq(help); - data.scene.next.name.should.to.be.eq('selection'); + // data.scene.next.name.should.to.be.eq('selection'); }); it('silence 3', async () => { diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index e1fc5776..cd70140d 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.currentBook.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "player_prequel.summarize" | "player_prequel.noSummary" | "player_prequel.help.1" | "player_prequel.enter.1" | "player_prequel.enter.2" | "player_prequel.enter.1-continue" | "player_prequel.enter.1-begin" | "player_prequel.enter.2-continue" | "player_prequel.enter.2-begin" | "player_prequel.summary.1" | "player.explain" | "player.start" | "player.start2" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1" | "noTitle", - "fr": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.currentBook.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "player_prequel.summarize" | "player_prequel.noSummary" | "player_prequel.help.1" | "player_prequel.enter.1" | "player_prequel.enter.2" | "player_prequel.enter.1-continue" | "player_prequel.enter.1-begin" | "player_prequel.enter.2-continue" | "player_prequel.enter.2-begin" | "player_prequel.summary.1" | "player.explain" | "player.start" | "player.start2" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1" | "noTitle" + "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.currentBook.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "player_prequel.summarize" | "player_prequel.noSummary" | "player_prequel.help.1" | "player_prequel.enter.1" | "player_prequel.enter.2" | "player_prequel.enter.1-continue" | "player_prequel.enter.1-begin" | "player_prequel.enter.2-continue" | "player_prequel.enter.2-begin" | "player_prequel.summary.1" | "player.explain" | "player.start" | "player.start2" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1" | "error.noBearerTokenInLinkedScene" | "noTitle", + "fr": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.currentBook.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "player_prequel.summarize" | "player_prequel.noSummary" | "player_prequel.help.1" | "player_prequel.enter.1" | "player_prequel.enter.2" | "player_prequel.enter.1-continue" | "player_prequel.enter.1-begin" | "player_prequel.enter.2-continue" | "player_prequel.enter.2-begin" | "player_prequel.summary.1" | "player.explain" | "player.start" | "player.start2" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1" | "error.noBearerTokenInLinkedScene" | "noTitle" }; keysWithNS: { - "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.currentBook.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:search.enter.2" | "en:search.empty.1" | "en:search.empty.2" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.nextPage.1" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:player_prequel.summarize" | "en:player_prequel.noSummary" | "en:player_prequel.help.1" | "en:player_prequel.enter.1" | "en:player_prequel.enter.2" | "en:player_prequel.enter.1-continue" | "en:player_prequel.enter.1-begin" | "en:player_prequel.enter.2-continue" | "en:player_prequel.enter.2-begin" | "en:player_prequel.summary.1" | "en:player.explain" | "en:player.start" | "en:player.start2" | "en:collections.enter.1" | "en:collections.help.1" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1" | "en:noTitle", - "fr": "fr:main.welcome.noLinked.1" | "fr:main.welcome.linked.1" | "fr:home_new_user.enter.first.1" | "fr:home_new_user.enter.first.2" | "fr:home_new_user.no.1" | "fr:home_new_user.no.2" | "fr:home_new_user.help.1" | "fr:home_new_user.help.2" | "fr:home_new_user.maybeLater.1" | "fr:home_new_user.maybeLater.2" | "fr:home_new_user_maybe_later.help.1" | "fr:home_new_user_no.help.1" | "fr:info.about.1" | "fr:info.help.1" | "fr:info.yesOrMembership.1" | "fr:home_user.enter.newlyUser.1" | "fr:home_user.enter.newlyUser.2" | "fr:home_user.enter.playing.1" | "fr:home_user.enter.playing.2" | "fr:home_user.enter.playing.3" | "fr:home_user.enter.regular.1" | "fr:home_user.currentBook.1" | "fr:home_user.help.1" | "fr:home_user.help.2" | "fr:search.enter.1" | "fr:search.enter.2" | "fr:search.empty.1" | "fr:search.empty.2" | "fr:selection.enter.bookshelf.first" | "fr:selection.enter.bookshelf.second" | "fr:selection.enter.search" | "fr:selection.enter.collection.publication" | "fr:selection.enter.collection.group" | "fr:selection.enter.lastPage.publication" | "fr:selection.enter.lastPage.group" | "fr:selection.enter.lastPage.notAvailable" | "fr:selection.enter.common.1" | "fr:selection.enter.common.2" | "fr:selection.enter.common.3" | "fr:selection.enter.nextPage.1" | "fr:selection.enter.empty.1" | "fr:selection.help.1" | "fr:player_prequel.summarize" | "fr:player_prequel.noSummary" | "fr:player_prequel.help.1" | "fr:player_prequel.enter.1" | "fr:player_prequel.enter.2" | "fr:player_prequel.enter.1-continue" | "fr:player_prequel.enter.1-begin" | "fr:player_prequel.enter.2-continue" | "fr:player_prequel.enter.2-begin" | "fr:player_prequel.summary.1" | "fr:player.explain" | "fr:player.start" | "fr:player.start2" | "fr:collections.enter.1" | "fr:collections.help.1" | "fr:void" | "fr:bye.1" | "fr:fallback.1" | "fr:fallback.2" | "fr:silence.1" | "fr:silence.2" | "fr:error.1" | "fr:noTitle" + "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.currentBook.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:search.enter.2" | "en:search.empty.1" | "en:search.empty.2" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.nextPage.1" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:player_prequel.summarize" | "en:player_prequel.noSummary" | "en:player_prequel.help.1" | "en:player_prequel.enter.1" | "en:player_prequel.enter.2" | "en:player_prequel.enter.1-continue" | "en:player_prequel.enter.1-begin" | "en:player_prequel.enter.2-continue" | "en:player_prequel.enter.2-begin" | "en:player_prequel.summary.1" | "en:player.explain" | "en:player.start" | "en:player.start2" | "en:collections.enter.1" | "en:collections.help.1" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1" | "en:error.noBearerTokenInLinkedScene" | "en:noTitle", + "fr": "fr:main.welcome.noLinked.1" | "fr:main.welcome.linked.1" | "fr:home_new_user.enter.first.1" | "fr:home_new_user.enter.first.2" | "fr:home_new_user.no.1" | "fr:home_new_user.no.2" | "fr:home_new_user.help.1" | "fr:home_new_user.help.2" | "fr:home_new_user.maybeLater.1" | "fr:home_new_user.maybeLater.2" | "fr:home_new_user_maybe_later.help.1" | "fr:home_new_user_no.help.1" | "fr:info.about.1" | "fr:info.help.1" | "fr:info.yesOrMembership.1" | "fr:home_user.enter.newlyUser.1" | "fr:home_user.enter.newlyUser.2" | "fr:home_user.enter.playing.1" | "fr:home_user.enter.playing.2" | "fr:home_user.enter.playing.3" | "fr:home_user.enter.regular.1" | "fr:home_user.currentBook.1" | "fr:home_user.help.1" | "fr:home_user.help.2" | "fr:search.enter.1" | "fr:search.enter.2" | "fr:search.empty.1" | "fr:search.empty.2" | "fr:selection.enter.bookshelf.first" | "fr:selection.enter.bookshelf.second" | "fr:selection.enter.search" | "fr:selection.enter.collection.publication" | "fr:selection.enter.collection.group" | "fr:selection.enter.lastPage.publication" | "fr:selection.enter.lastPage.group" | "fr:selection.enter.lastPage.notAvailable" | "fr:selection.enter.common.1" | "fr:selection.enter.common.2" | "fr:selection.enter.common.3" | "fr:selection.enter.nextPage.1" | "fr:selection.enter.empty.1" | "fr:selection.help.1" | "fr:player_prequel.summarize" | "fr:player_prequel.noSummary" | "fr:player_prequel.help.1" | "fr:player_prequel.enter.1" | "fr:player_prequel.enter.2" | "fr:player_prequel.enter.1-continue" | "fr:player_prequel.enter.1-begin" | "fr:player_prequel.enter.2-continue" | "fr:player_prequel.enter.2-begin" | "fr:player_prequel.summary.1" | "fr:player.explain" | "fr:player.start" | "fr:player.start2" | "fr:collections.enter.1" | "fr:collections.help.1" | "fr:void" | "fr:bye.1" | "fr:fallback.1" | "fr:fallback.2" | "fr:silence.1" | "fr:silence.2" | "fr:error.1" | "fr:error.noBearerTokenInLinkedScene" | "fr:noTitle" }; } diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index 12fd2aed..f606a9a1 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end' | 'player__on_enter' | 'player__intent__media_status_finished' | 'player__intent__media_status_paused' | 'player__intent__media_status_stopped' | 'player__intent__media_status_failed' | 'search__on_enter' | 'search__intent__search_query' | 'search__intent__search' | 'collections__on_enter' | 'collections__intent__bookshelf' | 'collections__intent__by_genre' | 'collections__intent__by_theme' | 'collections__intent__help' | 'collections__intent__fallback' | 'collections__intent__fallback_end' | 'collections__intent__silence' | 'collections__intent__silence_end' | 'player_prequel__on_enter' | 'home_user__intent__recent_books' | 'info__intent__no' | 'home_user__intent__current_book' | 'player_prequel__intent__help' | 'player_prequel__intent__repeat' | 'player_prequel__intent__player_prequel_back' | 'player_prequel__intent__player_prequel_resume' | 'player_prequel__intent__player_prequel_start' | 'player_prequel__intent__player_prequel_summary' | 'player_prequel__fallback' | 'player_prequel__fallback_end' | 'player_prequel__silence' | 'player_prequel__silence_end'; +export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end' | 'player__on_enter' | 'player__intent__media_status_finished' | 'player__intent__media_status_paused' | 'player__intent__media_status_stopped' | 'player__intent__media_status_failed' | 'search__on_enter' | 'search__intent__search_query' | 'search__intent__search' | 'collections__on_enter' | 'collections__intent__bookshelf' | 'collections__intent__by_genre' | 'collections__intent__by_theme' | 'collections__intent__help' | 'collections__intent__fallback' | 'collections__intent__fallback_end' | 'collections__intent__silence' | 'collections__intent__silence_end' | 'player_prequel__on_enter' | 'home_user__intent__recent_books' | 'info__intent__no' | 'home_user__intent__current_book' | 'player_prequel__intent__help' | 'player_prequel__intent__repeat' | 'player_prequel__intent__player_prequel_back' | 'player_prequel__intent__player_prequel_resume' | 'player_prequel__intent__player_prequel_start' | 'player_prequel__intent__player_prequel_summary' | 'player_prequel__fallback' | 'player_prequel__fallback_end' | 'player_prequel__silence' | 'player_prequel__silence_end' | 'player__intent__player_prequel_resume'; From 0cb469767b24f09dca3e92ed91b808d45188fbb3 Mon Sep 17 00:00:00 2001 From: Pierre Leroux <panacpp@gmail.com> Date: Mon, 11 Apr 2022 17:44:52 +0200 Subject: [PATCH 174/180] fix: linking issue when NOT_LINKED in authenticated scene create an assertion on authenticated scene tell to user an error happen and retry later then exit --- .../functions/src/controller/Assistant.ts | 27 ++++++++++++++++--- webhooks/functions/src/controller/Machine.ts | 5 ++++ webhooks/functions/src/translation/en/en.json | 3 ++- webhooks/functions/src/translation/fr/fr.json | 3 ++- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/webhooks/functions/src/controller/Assistant.ts b/webhooks/functions/src/controller/Assistant.ts index d2c0b249..547fdf58 100644 --- a/webhooks/functions/src/controller/Assistant.ts +++ b/webhooks/functions/src/controller/Assistant.ts @@ -9,6 +9,7 @@ import {enter as selectionEnter} from './handler/selection'; import {Machine} from './Machine'; import {ok} from 'assert'; import {WebpubError} from '../error'; +import {AccountLinkingStatus} from '@assistant/conversation/dist/api/schema'; export class Assistant { private _app: OmniHandler & BaseApp & ConversationV3App<ConversationV3>; @@ -68,7 +69,6 @@ export class Assistant { public handle = (path: TSdkHandler, fn: THandlerFn) => { this._app.handle(path, async (conv) => { - // @TODO need to send an alert to google log on timeout error const timerP = new Promise<void>((_, rej) => setTimeout(() => rej(new Error('TIMEOUT')), TIMER)); const machine = new Machine(conv); @@ -80,11 +80,30 @@ export class Assistant { await machine.setLanguage(locale); + const sceneName = conv.scene.name; + const linkingStatus = conv.user.accountLinkingStatus; + const linked = linkingStatus === AccountLinkingStatus.Linked; + const notLinked = !linked; + const bearerToken = linked ? conv.user.params.bearerToken : undefined; + console.info('ASSISTANT:', path); - console.info('scene.name=', conv.scene.name); - console.info('linkingStatus', conv.user.accountLinkingStatus); + console.info('scene.name=', sceneName); + console.info('linkingStatus', linkingStatus); + ok(sceneName, 'scene name not found'); + ok(linkingStatus, 'linking status not found'); + + const sceneWhereYouHaveToBeAuthenticated: TSdkScene[] = [ + 'collections', 'home_user', 'player', 'player_prequel', 'search', 'selection', + ]; + const linkedScene = sceneWhereYouHaveToBeAuthenticated.findIndex((v) => v === sceneName) > -1; + if (notLinked && linkedScene) { + machine.say('error.noBearerTokenInLinkedScene'); + + console.error('NOT_LINKED IN LINKED_SCENE', linkingStatus, bearerToken, sceneName, path); + machine.nextScene = 'actions.scene.END_CONVERSATION'; + return; + } - const bearerToken = conv.user.params.bearerToken; await machine.begin({bearerToken, storageModel: this._storageModel, fetcher: this._fetcher}); await Promise.race([timerP, Promise.resolve(fn(machine))]); diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index 26de3d10..cd7c64f8 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -51,6 +51,11 @@ export class Machine { this._model = storageModel; } else { if (typeof bearerToken === 'string') { + const Reset = '\x1b[0m'; + const FgRed = '\x1b[31m'; + + console.log(`${FgRed}BEARER=${bearerToken}${Reset}`); + this._model = await StorageModel.create(bearerToken); } else { console.info('No Bearer Token Available'); diff --git a/webhooks/functions/src/translation/en/en.json b/webhooks/functions/src/translation/en/en.json index 059b2f6f..a4341dc5 100644 --- a/webhooks/functions/src/translation/en/en.json +++ b/webhooks/functions/src/translation/en/en.json @@ -160,7 +160,8 @@ "2": "Sorry, I really don't hear well." }, "error": { - "1": "Oops, something went wrong. I will send you back to the home menu." + "1": "Oops, something went wrong. I will send you back to the home menu.", + "noBearerTokenInLinkedScene": "An issue occured during authentication, please retry later." }, "noTitle": "No title available" } diff --git a/webhooks/functions/src/translation/fr/fr.json b/webhooks/functions/src/translation/fr/fr.json index 5adfa300..a50f2ae8 100644 --- a/webhooks/functions/src/translation/fr/fr.json +++ b/webhooks/functions/src/translation/fr/fr.json @@ -160,7 +160,8 @@ "2": "Désolé, je n'entends vraiment pas bien." }, "error": { - "1": "Oups, quelque chose s'est mal passé. Je vous renvoie au menu d'accueil." + "1": "Oups, quelque chose s'est mal passé. Je vous renvoie au menu d'accueil.", + "noBearerTokenInLinkedScene": "Un problème est survenu lors de l'authentification, veuillez réessayer plus tard." }, "noTitle": "Aucun titre disponible" } From 59cf463cb470c01aabcd4d15a75f8e8feedbbc2d Mon Sep 17 00:00:00 2001 From: Pierre Leroux <panacpp@gmail.com> Date: Wed, 13 Apr 2022 16:20:38 +0200 Subject: [PATCH 175/180] fix: npm run typed --- webhooks/functions/src/typings/i18n.d.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/webhooks/functions/src/typings/i18n.d.ts b/webhooks/functions/src/typings/i18n.d.ts index cd70140d..c0a01188 100644 --- a/webhooks/functions/src/typings/i18n.d.ts +++ b/webhooks/functions/src/typings/i18n.d.ts @@ -3,11 +3,11 @@ export interface Translations { keys: { - "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.currentBook.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "player_prequel.summarize" | "player_prequel.noSummary" | "player_prequel.help.1" | "player_prequel.enter.1" | "player_prequel.enter.2" | "player_prequel.enter.1-continue" | "player_prequel.enter.1-begin" | "player_prequel.enter.2-continue" | "player_prequel.enter.2-begin" | "player_prequel.summary.1" | "player.explain" | "player.start" | "player.start2" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1" | "error.noBearerTokenInLinkedScene" | "noTitle", - "fr": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.currentBook.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "player_prequel.summarize" | "player_prequel.noSummary" | "player_prequel.help.1" | "player_prequel.enter.1" | "player_prequel.enter.2" | "player_prequel.enter.1-continue" | "player_prequel.enter.1-begin" | "player_prequel.enter.2-continue" | "player_prequel.enter.2-begin" | "player_prequel.summary.1" | "player.explain" | "player.start" | "player.start2" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1" | "error.noBearerTokenInLinkedScene" | "noTitle" + "en": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.enter.regular.2" | "home_user.currentBook.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "player_prequel.summarize" | "player_prequel.noSummary" | "player_prequel.help.1" | "player_prequel.enter.1" | "player_prequel.enter.2" | "player_prequel.enter.1-continue" | "player_prequel.enter.1-begin" | "player_prequel.enter.2-continue" | "player_prequel.enter.2-begin" | "player_prequel.summary.1" | "player.explain" | "player.start" | "player.start2" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1" | "error.noBearerTokenInLinkedScene" | "noTitle", + "fr": "main.welcome.noLinked.1" | "main.welcome.linked.1" | "home_new_user.enter.first.1" | "home_new_user.enter.first.2" | "home_new_user.no.1" | "home_new_user.no.2" | "home_new_user.help.1" | "home_new_user.help.2" | "home_new_user.maybeLater.1" | "home_new_user.maybeLater.2" | "home_new_user_maybe_later.help.1" | "home_new_user_no.help.1" | "info.about.1" | "info.help.1" | "info.yesOrMembership.1" | "home_user.enter.newlyUser.1" | "home_user.enter.newlyUser.2" | "home_user.enter.playing.1" | "home_user.enter.playing.2" | "home_user.enter.playing.3" | "home_user.enter.regular.1" | "home_user.enter.regular.2" | "home_user.currentBook.1" | "home_user.help.1" | "home_user.help.2" | "search.enter.1" | "search.enter.2" | "search.empty.1" | "search.empty.2" | "selection.enter.bookshelf.first" | "selection.enter.bookshelf.second" | "selection.enter.search" | "selection.enter.collection.publication" | "selection.enter.collection.group" | "selection.enter.lastPage.publication" | "selection.enter.lastPage.group" | "selection.enter.lastPage.notAvailable" | "selection.enter.common.1" | "selection.enter.common.2" | "selection.enter.common.3" | "selection.enter.nextPage.1" | "selection.enter.empty.1" | "selection.help.1" | "player_prequel.summarize" | "player_prequel.noSummary" | "player_prequel.help.1" | "player_prequel.enter.1" | "player_prequel.enter.2" | "player_prequel.enter.1-continue" | "player_prequel.enter.1-begin" | "player_prequel.enter.2-continue" | "player_prequel.enter.2-begin" | "player_prequel.summary.1" | "player.explain" | "player.start" | "player.start2" | "collections.enter.1" | "collections.help.1" | "void" | "bye.1" | "fallback.1" | "fallback.2" | "silence.1" | "silence.2" | "error.1" | "error.noBearerTokenInLinkedScene" | "noTitle" }; keysWithNS: { - "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.currentBook.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:search.enter.2" | "en:search.empty.1" | "en:search.empty.2" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.nextPage.1" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:player_prequel.summarize" | "en:player_prequel.noSummary" | "en:player_prequel.help.1" | "en:player_prequel.enter.1" | "en:player_prequel.enter.2" | "en:player_prequel.enter.1-continue" | "en:player_prequel.enter.1-begin" | "en:player_prequel.enter.2-continue" | "en:player_prequel.enter.2-begin" | "en:player_prequel.summary.1" | "en:player.explain" | "en:player.start" | "en:player.start2" | "en:collections.enter.1" | "en:collections.help.1" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1" | "en:error.noBearerTokenInLinkedScene" | "en:noTitle", - "fr": "fr:main.welcome.noLinked.1" | "fr:main.welcome.linked.1" | "fr:home_new_user.enter.first.1" | "fr:home_new_user.enter.first.2" | "fr:home_new_user.no.1" | "fr:home_new_user.no.2" | "fr:home_new_user.help.1" | "fr:home_new_user.help.2" | "fr:home_new_user.maybeLater.1" | "fr:home_new_user.maybeLater.2" | "fr:home_new_user_maybe_later.help.1" | "fr:home_new_user_no.help.1" | "fr:info.about.1" | "fr:info.help.1" | "fr:info.yesOrMembership.1" | "fr:home_user.enter.newlyUser.1" | "fr:home_user.enter.newlyUser.2" | "fr:home_user.enter.playing.1" | "fr:home_user.enter.playing.2" | "fr:home_user.enter.playing.3" | "fr:home_user.enter.regular.1" | "fr:home_user.currentBook.1" | "fr:home_user.help.1" | "fr:home_user.help.2" | "fr:search.enter.1" | "fr:search.enter.2" | "fr:search.empty.1" | "fr:search.empty.2" | "fr:selection.enter.bookshelf.first" | "fr:selection.enter.bookshelf.second" | "fr:selection.enter.search" | "fr:selection.enter.collection.publication" | "fr:selection.enter.collection.group" | "fr:selection.enter.lastPage.publication" | "fr:selection.enter.lastPage.group" | "fr:selection.enter.lastPage.notAvailable" | "fr:selection.enter.common.1" | "fr:selection.enter.common.2" | "fr:selection.enter.common.3" | "fr:selection.enter.nextPage.1" | "fr:selection.enter.empty.1" | "fr:selection.help.1" | "fr:player_prequel.summarize" | "fr:player_prequel.noSummary" | "fr:player_prequel.help.1" | "fr:player_prequel.enter.1" | "fr:player_prequel.enter.2" | "fr:player_prequel.enter.1-continue" | "fr:player_prequel.enter.1-begin" | "fr:player_prequel.enter.2-continue" | "fr:player_prequel.enter.2-begin" | "fr:player_prequel.summary.1" | "fr:player.explain" | "fr:player.start" | "fr:player.start2" | "fr:collections.enter.1" | "fr:collections.help.1" | "fr:void" | "fr:bye.1" | "fr:fallback.1" | "fr:fallback.2" | "fr:silence.1" | "fr:silence.2" | "fr:error.1" | "fr:error.noBearerTokenInLinkedScene" | "fr:noTitle" + "en": "en:main.welcome.noLinked.1" | "en:main.welcome.linked.1" | "en:home_new_user.enter.first.1" | "en:home_new_user.enter.first.2" | "en:home_new_user.no.1" | "en:home_new_user.no.2" | "en:home_new_user.help.1" | "en:home_new_user.help.2" | "en:home_new_user.maybeLater.1" | "en:home_new_user.maybeLater.2" | "en:home_new_user_maybe_later.help.1" | "en:home_new_user_no.help.1" | "en:info.about.1" | "en:info.help.1" | "en:info.yesOrMembership.1" | "en:home_user.enter.newlyUser.1" | "en:home_user.enter.newlyUser.2" | "en:home_user.enter.playing.1" | "en:home_user.enter.playing.2" | "en:home_user.enter.playing.3" | "en:home_user.enter.regular.1" | "en:home_user.enter.regular.2" | "en:home_user.currentBook.1" | "en:home_user.help.1" | "en:home_user.help.2" | "en:search.enter.1" | "en:search.enter.2" | "en:search.empty.1" | "en:search.empty.2" | "en:selection.enter.bookshelf.first" | "en:selection.enter.bookshelf.second" | "en:selection.enter.search" | "en:selection.enter.collection.publication" | "en:selection.enter.collection.group" | "en:selection.enter.lastPage.publication" | "en:selection.enter.lastPage.group" | "en:selection.enter.lastPage.notAvailable" | "en:selection.enter.common.1" | "en:selection.enter.common.2" | "en:selection.enter.common.3" | "en:selection.enter.nextPage.1" | "en:selection.enter.empty.1" | "en:selection.help.1" | "en:player_prequel.summarize" | "en:player_prequel.noSummary" | "en:player_prequel.help.1" | "en:player_prequel.enter.1" | "en:player_prequel.enter.2" | "en:player_prequel.enter.1-continue" | "en:player_prequel.enter.1-begin" | "en:player_prequel.enter.2-continue" | "en:player_prequel.enter.2-begin" | "en:player_prequel.summary.1" | "en:player.explain" | "en:player.start" | "en:player.start2" | "en:collections.enter.1" | "en:collections.help.1" | "en:void" | "en:bye.1" | "en:fallback.1" | "en:fallback.2" | "en:silence.1" | "en:silence.2" | "en:error.1" | "en:error.noBearerTokenInLinkedScene" | "en:noTitle", + "fr": "fr:main.welcome.noLinked.1" | "fr:main.welcome.linked.1" | "fr:home_new_user.enter.first.1" | "fr:home_new_user.enter.first.2" | "fr:home_new_user.no.1" | "fr:home_new_user.no.2" | "fr:home_new_user.help.1" | "fr:home_new_user.help.2" | "fr:home_new_user.maybeLater.1" | "fr:home_new_user.maybeLater.2" | "fr:home_new_user_maybe_later.help.1" | "fr:home_new_user_no.help.1" | "fr:info.about.1" | "fr:info.help.1" | "fr:info.yesOrMembership.1" | "fr:home_user.enter.newlyUser.1" | "fr:home_user.enter.newlyUser.2" | "fr:home_user.enter.playing.1" | "fr:home_user.enter.playing.2" | "fr:home_user.enter.playing.3" | "fr:home_user.enter.regular.1" | "fr:home_user.enter.regular.2" | "fr:home_user.currentBook.1" | "fr:home_user.help.1" | "fr:home_user.help.2" | "fr:search.enter.1" | "fr:search.enter.2" | "fr:search.empty.1" | "fr:search.empty.2" | "fr:selection.enter.bookshelf.first" | "fr:selection.enter.bookshelf.second" | "fr:selection.enter.search" | "fr:selection.enter.collection.publication" | "fr:selection.enter.collection.group" | "fr:selection.enter.lastPage.publication" | "fr:selection.enter.lastPage.group" | "fr:selection.enter.lastPage.notAvailable" | "fr:selection.enter.common.1" | "fr:selection.enter.common.2" | "fr:selection.enter.common.3" | "fr:selection.enter.nextPage.1" | "fr:selection.enter.empty.1" | "fr:selection.help.1" | "fr:player_prequel.summarize" | "fr:player_prequel.noSummary" | "fr:player_prequel.help.1" | "fr:player_prequel.enter.1" | "fr:player_prequel.enter.2" | "fr:player_prequel.enter.1-continue" | "fr:player_prequel.enter.1-begin" | "fr:player_prequel.enter.2-continue" | "fr:player_prequel.enter.2-begin" | "fr:player_prequel.summary.1" | "fr:player.explain" | "fr:player.start" | "fr:player.start2" | "fr:collections.enter.1" | "fr:collections.help.1" | "fr:void" | "fr:bye.1" | "fr:fallback.1" | "fr:fallback.2" | "fr:silence.1" | "fr:silence.2" | "fr:error.1" | "fr:error.noBearerTokenInLinkedScene" | "fr:noTitle" }; } From 7492847ec483ff5ad895278a4b48827be4af4ebd Mon Sep 17 00:00:00 2001 From: Pierre Leroux <panacpp@gmail.com> Date: Thu, 14 Apr 2022 12:24:00 +0200 Subject: [PATCH 176/180] fix: the crash on undefined object querySearch and selectBookNumber --- webhooks/functions/src/controller/Machine.ts | 22 ++++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index cd7c64f8..bb68eab7 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -407,18 +407,22 @@ export class Machine { } public get selectBookNumber() { - const v = this._conv.intent.params?.number.resolved; - if (v && typeof v === 'number') { - return v; - } + try { + const v = this._conv.intent.params?.number.resolved; + if (v && typeof v === 'number') { + return v; + } + } catch {} return undefined; } public get querySearch() { - const v = this._conv.intent.params?.query?.resolved; - if (v && typeof v === 'string') { - return v; - } + try { + const v = this._conv.intent.params?.query?.resolved; + if (v && typeof v === 'string') { + return v; + } + } catch {} return undefined; } @@ -527,7 +531,7 @@ export class Machine { } ok(this._model); - const _progress = this._conv.context?.media?.progress || '0'; + const _progress = this._conv.context.media?.progress || '0'; const progress = finished ? 0 : parseInt(_progress, 10); const index = finished ? 0 : (this._conv.request.context?.media?.index || 0); const url = this._model.store.player.current.url; From 66f1458dbfde139362fdafd39193ed93661aaf89 Mon Sep 17 00:00:00 2001 From: Pierre Leroux <panacpp@gmail.com> Date: Thu, 14 Apr 2022 11:36:44 +0200 Subject: [PATCH 177/180] fix: player startIndex --- webhooks/functions/src/controller/Machine.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index bb68eab7..d74eb482 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -609,7 +609,7 @@ export class Machine { url: webpub.cover || '', }, }, - })).slice(startIndex); + })); console.log('Media list'); console.log(mediaObjects); @@ -621,6 +621,7 @@ export class Machine { mediaType: MediaType.Audio, optionalMediaControls: [OptionalMediaControl.Paused, OptionalMediaControl.Stopped], startOffset: `${startTime}s`, + firstMediaObjectIndex: startIndex, }), ); } From c5bbde518c7ef08ae4818ab522e233990286248d Mon Sep 17 00:00:00 2001 From: Pierre Leroux <panacpp@gmail.com> Date: Thu, 14 Apr 2022 11:31:34 +0200 Subject: [PATCH 178/180] sdk: follow previous commit resume in player scene --- webhooks/functions/src/controller/handler/player.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/webhooks/functions/src/controller/handler/player.ts b/webhooks/functions/src/controller/handler/player.ts index 4f85535e..69ebc03f 100644 --- a/webhooks/functions/src/controller/handler/player.ts +++ b/webhooks/functions/src/controller/handler/player.ts @@ -8,7 +8,6 @@ export const player = (app: Assistant) => { app.handle("player__intent__media_status_finished", finished); app.handle("player__intent__media_status_paused", paused); app.handle("player__intent__media_status_failed", failed); - app.handle("player__intent__player_prequel_resume", resume); } From a27a84afe34ae20e1539221f9a08222922d606eb Mon Sep 17 00:00:00 2001 From: Pierre Leroux <panacpp@gmail.com> Date: Thu, 14 Apr 2022 11:27:33 +0200 Subject: [PATCH 179/180] sdk: remove resume in player scene --- sdk/custom/scenes/player.yaml | 3 --- sdk/webhooks/ActionsOnGoogleFulfillment.yaml | 1 - webhooks/functions/src/controller/handler/player.ts | 6 +----- webhooks/functions/src/sdk/player.test.ts | 3 --- webhooks/functions/src/typings/sdkHandler.d.ts | 2 +- 5 files changed, 2 insertions(+), 13 deletions(-) diff --git a/sdk/custom/scenes/player.yaml b/sdk/custom/scenes/player.yaml index 7b39989b..e9c731a7 100644 --- a/sdk/custom/scenes/player.yaml +++ b/sdk/custom/scenes/player.yaml @@ -1,7 +1,4 @@ intentEvents: -- handler: - webhookHandler: player__intent__player_prequel_resume - intent: player_prequel_resume - handler: webhookHandler: player__intent__media_status_finished intent: actions.intent.MEDIA_STATUS_FINISHED diff --git a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml index 66923e65..5da8b1a1 100644 --- a/sdk/webhooks/ActionsOnGoogleFulfillment.yaml +++ b/sdk/webhooks/ActionsOnGoogleFulfillment.yaml @@ -93,7 +93,6 @@ handlers: - name: player_prequel__fallback_end - name: player_prequel__silence - name: player_prequel__silence_end -- name: player__intent__player_prequel_resume httpsEndpoint: baseUrl: https://us-central1-edrlab-1.cloudfunctions.net/ActionsOnGoogleFulfillment endpointApiVersion: 2 diff --git a/webhooks/functions/src/controller/handler/player.ts b/webhooks/functions/src/controller/handler/player.ts index 69ebc03f..f51eb862 100644 --- a/webhooks/functions/src/controller/handler/player.ts +++ b/webhooks/functions/src/controller/handler/player.ts @@ -36,13 +36,9 @@ const failed: THandlerFn = async (m) => { m.nextScene = "home_user"; } -const resume: THandlerFn = async (m) => { - await m.player(); -} - const finished: THandlerFn = async (m) => { m.persistMediaPlayer(true); m.nextScene = "home_user"; -}; \ No newline at end of file +}; diff --git a/webhooks/functions/src/sdk/player.test.ts b/webhooks/functions/src/sdk/player.test.ts index 9a908215..bfc40655 100644 --- a/webhooks/functions/src/sdk/player.test.ts +++ b/webhooks/functions/src/sdk/player.test.ts @@ -11,9 +11,6 @@ chai.should(); const scene = 'player'; const yaml = `intentEvents: -- handler: - webhookHandler: player__intent__player_prequel_resume - intent: player_prequel_resume - handler: webhookHandler: player__intent__media_status_finished intent: actions.intent.MEDIA_STATUS_FINISHED diff --git a/webhooks/functions/src/typings/sdkHandler.d.ts b/webhooks/functions/src/typings/sdkHandler.d.ts index f606a9a1..12fd2aed 100644 --- a/webhooks/functions/src/typings/sdkHandler.d.ts +++ b/webhooks/functions/src/typings/sdkHandler.d.ts @@ -1,4 +1,4 @@ // npm run handler-typed ; -export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end' | 'player__on_enter' | 'player__intent__media_status_finished' | 'player__intent__media_status_paused' | 'player__intent__media_status_stopped' | 'player__intent__media_status_failed' | 'search__on_enter' | 'search__intent__search_query' | 'search__intent__search' | 'collections__on_enter' | 'collections__intent__bookshelf' | 'collections__intent__by_genre' | 'collections__intent__by_theme' | 'collections__intent__help' | 'collections__intent__fallback' | 'collections__intent__fallback_end' | 'collections__intent__silence' | 'collections__intent__silence_end' | 'player_prequel__on_enter' | 'home_user__intent__recent_books' | 'info__intent__no' | 'home_user__intent__current_book' | 'player_prequel__intent__help' | 'player_prequel__intent__repeat' | 'player_prequel__intent__player_prequel_back' | 'player_prequel__intent__player_prequel_resume' | 'player_prequel__intent__player_prequel_start' | 'player_prequel__intent__player_prequel_summary' | 'player_prequel__fallback' | 'player_prequel__fallback_end' | 'player_prequel__silence' | 'player_prequel__silence_end' | 'player__intent__player_prequel_resume'; +export type TSdkHandler = 'main' | 'home_new_user__intent__help' | 'home_new_user__intent__maybe_later' | 'home_new_user__intent__no' | 'home_new_user__intent__repeat' | 'home_new_user__intent__yes' | 'home_new_user__intent__fallback' | 'home_new_user__intent__fallback_end' | 'home_new_user__intent__silence' | 'home_new_user__intent__silence_end' | 'home_new_user_maybe_later__intent__learn_more' | 'home_new_user_maybe_later__intent__repeat' | 'home_new_user_maybe_later__intent__link_account' | 'home_new_user_maybe_later__intent__help' | 'home_new_user_maybe_later__intent__fallback' | 'home_new_user_maybe_later__intent__fallback_end' | 'home_new_user_maybe_later__intent__silence' | 'home_new_user_maybe_later__intent__silence_end' | 'info__intent__yes' | 'info__intent__help' | 'info__intent__repeat' | 'info__intent__fallback' | 'info__intent__fallback_end' | 'info__intent__silence' | 'info__intent__silence_end' | 'home_new_user_no__intent__yes' | 'home_new_user_no__intent__no' | 'home_new_user_no__intent__repeat' | 'home_new_user_no__intent__help' | 'home_new_user_no__intent__fallback' | 'home_new_user_no__intent__fallback_end' | 'home_new_user_no__intent__silence' | 'home_new_user_no__intent__silence_end' | 'cancel' | 'home_new_user__on_enter' | 'home_new_user_no__on_enter' | 'home_new_user_maybe_later__on_enter' | 'info__on_enter' | 'home_user__on_enter' | 'home_user__intent__help' | 'home_user__intent__repeat' | 'home_user__intent__bookshelf' | 'home_user__intent__collections' | 'home_user__intent__search' | 'home_user__intent__fallback' | 'home_user__intent__fallback_end' | 'home_user__intent__silence' | 'home_user__intent__silence_end' | 'selection__on_enter' | 'selection__intent__selects_book' | 'selection__intent__repeat' | 'selection__intent__another_one' | 'selection__intent__help' | 'selection__intent__fallback' | 'selection__intent__fallback_end' | 'selection__intent__silence' | 'selection__intent__silence_end' | 'fallback_1' | 'fallback_2' | 'fallback_end' | 'silence_1' | 'silence_2' | 'silence_end' | 'player__on_enter' | 'player__intent__media_status_finished' | 'player__intent__media_status_paused' | 'player__intent__media_status_stopped' | 'player__intent__media_status_failed' | 'search__on_enter' | 'search__intent__search_query' | 'search__intent__search' | 'collections__on_enter' | 'collections__intent__bookshelf' | 'collections__intent__by_genre' | 'collections__intent__by_theme' | 'collections__intent__help' | 'collections__intent__fallback' | 'collections__intent__fallback_end' | 'collections__intent__silence' | 'collections__intent__silence_end' | 'player_prequel__on_enter' | 'home_user__intent__recent_books' | 'info__intent__no' | 'home_user__intent__current_book' | 'player_prequel__intent__help' | 'player_prequel__intent__repeat' | 'player_prequel__intent__player_prequel_back' | 'player_prequel__intent__player_prequel_resume' | 'player_prequel__intent__player_prequel_start' | 'player_prequel__intent__player_prequel_summary' | 'player_prequel__fallback' | 'player_prequel__fallback_end' | 'player_prequel__silence' | 'player_prequel__silence_end'; From 9efd24285a9f9c0603bc4756e08c002741a43ae2 Mon Sep 17 00:00:00 2001 From: Pierre Leroux <panacpp@gmail.com> Date: Thu, 14 Apr 2022 11:31:10 +0200 Subject: [PATCH 180/180] fix: sessionId changed during user session I reset the session only when the path equal home_user__on_enter --- .../functions/src/controller/Assistant.ts | 2 +- webhooks/functions/src/controller/Machine.ts | 30 ++++++++----------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/webhooks/functions/src/controller/Assistant.ts b/webhooks/functions/src/controller/Assistant.ts index 547fdf58..b32684f3 100644 --- a/webhooks/functions/src/controller/Assistant.ts +++ b/webhooks/functions/src/controller/Assistant.ts @@ -104,7 +104,7 @@ export class Assistant { return; } - await machine.begin({bearerToken, storageModel: this._storageModel, fetcher: this._fetcher}); + await machine.begin({bearerToken, storageModel: this._storageModel, fetcher: this._fetcher, path}); await Promise.race([timerP, Promise.resolve(fn(machine))]); diff --git a/webhooks/functions/src/controller/Machine.ts b/webhooks/functions/src/controller/Machine.ts index d74eb482..2386688f 100644 --- a/webhooks/functions/src/controller/Machine.ts +++ b/webhooks/functions/src/controller/Machine.ts @@ -40,10 +40,12 @@ export class Machine { storageModel, bearerToken, fetcher, + path, }: { storageModel?: StorageModel, bearerToken?: string, fetcher?: OpdsFetcher; + path: TSdkHandler; }) { console.info('Machine BEGIN'); @@ -81,7 +83,7 @@ export class Machine { } // check new Session and keep or remove the data session - this.removeSessionDataWhenNewUserSession(); + this.removeSessionDataWhenNewUserSession(path); } public async end() { @@ -688,24 +690,18 @@ export class Machine { return feed; }); - private removeSessionDataWhenNewUserSession() { + private removeSessionDataWhenNewUserSession(p: TSdkHandler) { if (!this._model) { return; } - const id = this._conv.session.id; - if (!id) { - return; - } - const idFromStore = this._model.store.user.sessionId; - if (!idFromStore) { - console.info('no user session id saved in database'); - } - const sameSession = id === idFromStore; - if (sameSession) { - console.info('MIDDLEWARE :: Session in progress'); - // see home_user.ts - // this.setSessionState('home_user', 'SESSION'); - } else { + + // the sessionId from google is not regular when a user session is in progress + // if homeUserScene then reset the session + + if (p === 'home_user__on_enter') { + const id = this._conv.session.id; + + // reset session ! console.info('MIDDLEWARE :: new SESSION'); this._model.store.session = { scene: { @@ -725,7 +721,7 @@ export class Machine { }, }, }; - this._model.store.user.sessionId = id; + this._model.store.user.sessionId = id || 'no ID'; } }