From 4bea995375d4722679cefeaea5105cc3a960ff9d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 18:44:46 +0000 Subject: [PATCH 1/3] Bump @sentry/node from 7.73.0 to 7.74.0 Bumps [@sentry/node](https://github.com/getsentry/sentry-javascript) from 7.73.0 to 7.74.0. - [Release notes](https://github.com/getsentry/sentry-javascript/releases) - [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-javascript/compare/7.73.0...7.74.0) --- updated-dependencies: - dependency-name: "@sentry/node" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 96 +++++++++++++++++++++++++++++++++++++++-------- package.json | 2 +- 2 files changed, 82 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index a104198..1c44720 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "GPL-3.0+", "dependencies": { "@sentry/integrations": "^7.72.0", - "@sentry/node": "^7.72.0", + "@sentry/node": "^7.74.0", "@slack/bolt": "^3.13.0", "cheerio": "^1.0.0-rc.10", "dotenv": "^16.3.1", @@ -215,13 +215,46 @@ } }, "node_modules/@sentry-internal/tracing": { - "version": "7.73.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.73.0.tgz", - "integrity": "sha512-ig3WL/Nqp8nRQ52P205NaypGKNfIl/G+cIqge9xPW6zfRb5kJdM1YParw9GSJ1SPjEZBkBORGAML0on5H2FILw==", + "version": "7.74.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.74.0.tgz", + "integrity": "sha512-JK6IRGgdtZjswGfaGIHNWIThffhOHzVIIaGmglui+VFIzOsOqePjoxaDV0MEvzafxXZD7eWqGE5RGuZ0n6HFVg==", "dependencies": { - "@sentry/core": "7.73.0", - "@sentry/types": "7.73.0", - "@sentry/utils": "7.73.0", + "@sentry/core": "7.74.0", + "@sentry/types": "7.74.0", + "@sentry/utils": "7.74.0", + "tslib": "^2.4.1 || ^1.9.3" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry-internal/tracing/node_modules/@sentry/core": { + "version": "7.74.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.74.0.tgz", + "integrity": "sha512-83NRuqn7nDZkSVBN5yJQqcpXDG4yMYiB7TkYUKrGTzBpRy6KUOrkCdybuKk0oraTIGiGSe5WEwCFySiNgR9FzA==", + "dependencies": { + "@sentry/types": "7.74.0", + "@sentry/utils": "7.74.0", + "tslib": "^2.4.1 || ^1.9.3" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry-internal/tracing/node_modules/@sentry/types": { + "version": "7.74.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.74.0.tgz", + "integrity": "sha512-rI5eIRbUycWjn6s6o3yAjjWtIvYSxZDdnKv5je2EZINfLKcMPj1dkl6wQd2F4y7gLfD/N6Y0wZYIXC3DUdJQQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry-internal/tracing/node_modules/@sentry/utils": { + "version": "7.74.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.74.0.tgz", + "integrity": "sha512-k3np8nuTPtx5KDODPtULfFln4UXdE56MZCcF19Jv6Ljxf+YN/Ady1+0Oi3e0XoSvFpWNyWnglauT7M65qCE6kg==", + "dependencies": { + "@sentry/types": "7.74.0", "tslib": "^2.4.1 || ^1.9.3" }, "engines": { @@ -319,14 +352,14 @@ } }, "node_modules/@sentry/node": { - "version": "7.73.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.73.0.tgz", - "integrity": "sha512-i50bRfmgkRRx0XXUbg9jGD/RuznDJxJXc4rBILhoJuhl+BjRIaoXA3ayplfJn8JLZxsNh75uJaCq4IUK70SORw==", - "dependencies": { - "@sentry-internal/tracing": "7.73.0", - "@sentry/core": "7.73.0", - "@sentry/types": "7.73.0", - "@sentry/utils": "7.73.0", + "version": "7.74.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.74.0.tgz", + "integrity": "sha512-uBmW2/z0cz/WFIG74ZF7lSipO0XNzMf9yrdqnZXnGDYsUZE4I4QiqDN0hNi6fkTgf9MYRC8uFem2OkAvyPJ74Q==", + "dependencies": { + "@sentry-internal/tracing": "7.74.0", + "@sentry/core": "7.74.0", + "@sentry/types": "7.74.0", + "@sentry/utils": "7.74.0", "cookie": "^0.5.0", "https-proxy-agent": "^5.0.0", "lru_map": "^0.3.3", @@ -336,6 +369,39 @@ "node": ">=8" } }, + "node_modules/@sentry/node/node_modules/@sentry/core": { + "version": "7.74.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.74.0.tgz", + "integrity": "sha512-83NRuqn7nDZkSVBN5yJQqcpXDG4yMYiB7TkYUKrGTzBpRy6KUOrkCdybuKk0oraTIGiGSe5WEwCFySiNgR9FzA==", + "dependencies": { + "@sentry/types": "7.74.0", + "@sentry/utils": "7.74.0", + "tslib": "^2.4.1 || ^1.9.3" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry/node/node_modules/@sentry/types": { + "version": "7.74.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.74.0.tgz", + "integrity": "sha512-rI5eIRbUycWjn6s6o3yAjjWtIvYSxZDdnKv5je2EZINfLKcMPj1dkl6wQd2F4y7gLfD/N6Y0wZYIXC3DUdJQQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry/node/node_modules/@sentry/utils": { + "version": "7.74.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.74.0.tgz", + "integrity": "sha512-k3np8nuTPtx5KDODPtULfFln4UXdE56MZCcF19Jv6Ljxf+YN/Ady1+0Oi3e0XoSvFpWNyWnglauT7M65qCE6kg==", + "dependencies": { + "@sentry/types": "7.74.0", + "tslib": "^2.4.1 || ^1.9.3" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@sentry/types": { "version": "7.73.0", "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.73.0.tgz", diff --git a/package.json b/package.json index 6177e66..de743f4 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ }, "dependencies": { "@sentry/integrations": "^7.72.0", - "@sentry/node": "^7.72.0", + "@sentry/node": "^7.74.0", "@slack/bolt": "^3.13.0", "cheerio": "^1.0.0-rc.10", "dotenv": "^16.3.1", From 4ee8f4c43cb643d80d5fcd3d4a615aecb6ef95f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Oct 2023 17:55:21 +0000 Subject: [PATCH 2/3] Bump @sentry/integrations from 7.73.0 to 7.74.0 Bumps [@sentry/integrations](https://github.com/getsentry/sentry-javascript) from 7.73.0 to 7.74.0. - [Release notes](https://github.com/getsentry/sentry-javascript/releases) - [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-javascript/compare/7.73.0...7.74.0) --- updated-dependencies: - dependency-name: "@sentry/integrations" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 94 +++++++---------------------------------------- package.json | 2 +- 2 files changed, 15 insertions(+), 81 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1c44720..cd2ff77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.8.0", "license": "GPL-3.0+", "dependencies": { - "@sentry/integrations": "^7.72.0", + "@sentry/integrations": "^7.74.0", "@sentry/node": "^7.74.0", "@slack/bolt": "^3.13.0", "cheerio": "^1.0.0-rc.10", @@ -228,39 +228,6 @@ "node": ">=8" } }, - "node_modules/@sentry-internal/tracing/node_modules/@sentry/core": { - "version": "7.74.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.74.0.tgz", - "integrity": "sha512-83NRuqn7nDZkSVBN5yJQqcpXDG4yMYiB7TkYUKrGTzBpRy6KUOrkCdybuKk0oraTIGiGSe5WEwCFySiNgR9FzA==", - "dependencies": { - "@sentry/types": "7.74.0", - "@sentry/utils": "7.74.0", - "tslib": "^2.4.1 || ^1.9.3" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry-internal/tracing/node_modules/@sentry/types": { - "version": "7.74.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.74.0.tgz", - "integrity": "sha512-rI5eIRbUycWjn6s6o3yAjjWtIvYSxZDdnKv5je2EZINfLKcMPj1dkl6wQd2F4y7gLfD/N6Y0wZYIXC3DUdJQQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry-internal/tracing/node_modules/@sentry/utils": { - "version": "7.74.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.74.0.tgz", - "integrity": "sha512-k3np8nuTPtx5KDODPtULfFln4UXdE56MZCcF19Jv6Ljxf+YN/Ady1+0Oi3e0XoSvFpWNyWnglauT7M65qCE6kg==", - "dependencies": { - "@sentry/types": "7.74.0", - "tslib": "^2.4.1 || ^1.9.3" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@sentry/cli": { "version": "2.21.2", "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.21.2.tgz", @@ -324,12 +291,12 @@ } }, "node_modules/@sentry/core": { - "version": "7.73.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.73.0.tgz", - "integrity": "sha512-9FEz4Gq848LOgVN2OxJGYuQqxv7cIVw69VlAzWHEm3njt8mjvlTq+7UiFsGRo84+59V2FQuHxzA7vVjl90WfSg==", + "version": "7.74.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.74.0.tgz", + "integrity": "sha512-83NRuqn7nDZkSVBN5yJQqcpXDG4yMYiB7TkYUKrGTzBpRy6KUOrkCdybuKk0oraTIGiGSe5WEwCFySiNgR9FzA==", "dependencies": { - "@sentry/types": "7.73.0", - "@sentry/utils": "7.73.0", + "@sentry/types": "7.74.0", + "@sentry/utils": "7.74.0", "tslib": "^2.4.1 || ^1.9.3" }, "engines": { @@ -337,13 +304,13 @@ } }, "node_modules/@sentry/integrations": { - "version": "7.73.0", - "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.73.0.tgz", - "integrity": "sha512-IjVpn4d+aSL9L1Ntu/oAdRwujz4BzzavDsZf96Xgc/AjBnjAEUT+wT1dAwluThfuKDXmWOJHhZ2cHHMfqI+7vw==", + "version": "7.74.0", + "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.74.0.tgz", + "integrity": "sha512-O4UyxiV5wzXSDnEd9Z/SIt/5M12URWNtIJPPJjowlllzw8X9e3zBcnXmjMOLZ+mZWjQmRDjOoz3lPPQ17f7fvw==", "dependencies": { - "@sentry/core": "7.73.0", - "@sentry/types": "7.73.0", - "@sentry/utils": "7.73.0", + "@sentry/core": "7.74.0", + "@sentry/types": "7.74.0", + "@sentry/utils": "7.74.0", "localforage": "^1.8.1", "tslib": "^2.4.1 || ^1.9.3" }, @@ -369,20 +336,7 @@ "node": ">=8" } }, - "node_modules/@sentry/node/node_modules/@sentry/core": { - "version": "7.74.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.74.0.tgz", - "integrity": "sha512-83NRuqn7nDZkSVBN5yJQqcpXDG4yMYiB7TkYUKrGTzBpRy6KUOrkCdybuKk0oraTIGiGSe5WEwCFySiNgR9FzA==", - "dependencies": { - "@sentry/types": "7.74.0", - "@sentry/utils": "7.74.0", - "tslib": "^2.4.1 || ^1.9.3" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/node/node_modules/@sentry/types": { + "node_modules/@sentry/types": { "version": "7.74.0", "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.74.0.tgz", "integrity": "sha512-rI5eIRbUycWjn6s6o3yAjjWtIvYSxZDdnKv5je2EZINfLKcMPj1dkl6wQd2F4y7gLfD/N6Y0wZYIXC3DUdJQQg==", @@ -390,7 +344,7 @@ "node": ">=8" } }, - "node_modules/@sentry/node/node_modules/@sentry/utils": { + "node_modules/@sentry/utils": { "version": "7.74.0", "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.74.0.tgz", "integrity": "sha512-k3np8nuTPtx5KDODPtULfFln4UXdE56MZCcF19Jv6Ljxf+YN/Ady1+0Oi3e0XoSvFpWNyWnglauT7M65qCE6kg==", @@ -402,26 +356,6 @@ "node": ">=8" } }, - "node_modules/@sentry/types": { - "version": "7.73.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.73.0.tgz", - "integrity": "sha512-/v8++bly8jW7r4cP2wswYiiVpn7eLLcqwnfPUMeCQze4zj3F3nTRIKc9BGHzU0V+fhHa3RwRC2ksqTGq1oJMDg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/utils": { - "version": "7.73.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.73.0.tgz", - "integrity": "sha512-h3ZK/qpf4k76FhJV9uiSbvMz3V/0Ovy94C+5/9UgPMVCJXFmVsdw8n/dwANJ7LupVPfYP23xFGgebDMFlK1/2w==", - "dependencies": { - "@sentry/types": "7.73.0", - "tslib": "^2.4.1 || ^1.9.3" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@slack/bolt": { "version": "3.14.0", "resolved": "https://registry.npmjs.org/@slack/bolt/-/bolt-3.14.0.tgz", diff --git a/package.json b/package.json index de743f4..cb7d8fd 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "typescript": "^5.0.2" }, "dependencies": { - "@sentry/integrations": "^7.72.0", + "@sentry/integrations": "^7.74.0", "@sentry/node": "^7.74.0", "@slack/bolt": "^3.13.0", "cheerio": "^1.0.0-rc.10", From fb53ea02e81c95c1f2464d54df4fc323286450f3 Mon Sep 17 00:00:00 2001 From: Jani Haiko Date: Sat, 14 Oct 2023 22:37:07 +0300 Subject: [PATCH 3/3] Code cleaning, fixes --- .eslintrc.json | 4 +- package-lock.json | 97 +++++++++++++++---- package.json | 5 +- resources/manifest.yml | 4 +- src/AdminEvents.ts | 4 +- src/BlockParsers.ts | 15 +-- src/BotActions.ts | 5 +- src/BotCommands.ts | 19 +++- src/BotEvents.ts | 25 ++--- src/Utils.ts | 5 +- src/model/LounasRepository.ts | 5 +- src/model/Settings.ts | 29 ++++-- src/model/SettingsRepository.ts | 5 +- src/model/dataProviders/LounasDataProvider.ts | 2 +- src/model/dataProviders/MockDataProvider.ts | 4 +- .../RuokapaikkaFiDataProvider.ts | 15 ++- src/model/dataProviders/TalliDataProvider.ts | 11 +-- src/model/dataProviders/VaihaDataProvider.ts | 11 +-- src/server.ts | 21 ++-- src/types.d.ts | 4 +- 20 files changed, 187 insertions(+), 103 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 573244a..26461b5 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -8,7 +8,9 @@ "plugin:import/recommended", "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended", - "plugin:import/typescript" + "plugin:import/typescript", + "alloy", + "alloy/typescript" ], "parser": "@typescript-eslint/parser", "parserOptions": { diff --git a/package-lock.json b/package-lock.json index cd2ff77..4c31d08 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "lounasbotti", - "version": "1.8.0", + "version": "1.8.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "lounasbotti", - "version": "1.8.0", + "version": "1.8.1", "license": "GPL-3.0+", "dependencies": { "@sentry/integrations": "^7.74.0", @@ -26,6 +26,7 @@ "@typescript-eslint/eslint-plugin": "^5.39.0", "@typescript-eslint/parser": "^5.39.0", "eslint": "^8.45.0", + "eslint-config-alloy": "^5.1.2", "eslint-import-resolver-typescript": "^3.3.0", "eslint-plugin-import": "^2.27.5", "ts-node": "^10.9.1", @@ -561,9 +562,9 @@ } }, "node_modules/@types/express": { - "version": "4.17.18", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.18.tgz", - "integrity": "sha512-Sxv8BSLLgsBYmcnGdGjjEjqET2U+AKAdCRODmMiq02FgjwuV75Ut85DRpvFjyw/Mk0vgUOliGRU0UUmuuZHByQ==", + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.19.tgz", + "integrity": "sha512-UtOfBtzN9OvpZPPbnnYunfjM7XCI4jyk1NvnFhTVz5krYAnW4o5DCoIekvms+8ApqhB4+9wSge1kBijdfTSmfg==", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -621,9 +622,12 @@ "integrity": "sha512-Ys+/St+2VF4+xuY6+kDIXGxbNRO0mesVg0bbxEfB97Od1Vjpjx9KD1qxs64Gcb3CWPirk9Xe+PT4YiiHQ9T+eg==" }, "node_modules/@types/node": { - "version": "20.8.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.3.tgz", - "integrity": "sha512-jxiZQFpb+NlH5kjW49vXxvxTjeeqlbsnTAdBTKpzEdPs9itay7MscYXz3Fo9VYFEsfQ6LJFitHad3faerLAjCw==" + "version": "20.8.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.6.tgz", + "integrity": "sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==", + "dependencies": { + "undici-types": "~5.25.1" + } }, "node_modules/@types/node-schedule": { "version": "2.1.1", @@ -1512,9 +1516,9 @@ "dev": true }, "node_modules/define-data-property": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.0.tgz", - "integrity": "sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", "dependencies": { "get-intrinsic": "^1.2.1", "gopd": "^1.0.1", @@ -1890,6 +1894,49 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-config-alloy": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/eslint-config-alloy/-/eslint-config-alloy-5.1.2.tgz", + "integrity": "sha512-jppzCxNqlhvMYPgfUzvPq4f9fEu070+m3CRIjWdUx/GJLZ6dXHARzMIrIhFuIvzYI5Qo40ht1gunguLnRhIB7A==", + "dev": true, + "peerDependencies": { + "@babel/eslint-parser": "7.x", + "@babel/preset-react": "7.x", + "@typescript-eslint/eslint-plugin": ">=5.55.0", + "@typescript-eslint/parser": ">=5.0.0", + "eslint": ">=8.24.0", + "eslint-plugin-react": ">=7.31.8", + "eslint-plugin-vue": ">=9.5.1", + "typescript": "5.x", + "vue-eslint-parser": "9.x" + }, + "peerDependenciesMeta": { + "@babel/eslint-parser": { + "optional": true + }, + "@babel/preset-react": { + "optional": true + }, + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "@typescript-eslint/parser": { + "optional": true + }, + "eslint-plugin-react": { + "optional": true + }, + "eslint-plugin-vue": { + "optional": true + }, + "typescript": { + "optional": true + }, + "vue-eslint-parser": { + "optional": true + } + } + }, "node_modules/eslint-import-resolver-node": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", @@ -2467,9 +2514,12 @@ "dev": true }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/function.prototype.name": { "version": "1.1.6", @@ -3512,11 +3562,11 @@ } }, "node_modules/mongoose": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-7.6.0.tgz", - "integrity": "sha512-ztQ12rm0BQN5i7LB6xhWX4l9a9w2aa3jEwa/mM2vAutYJRyAwOzcusvKJBULMzFHyUDBOVW15grisexypgMIWA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-7.6.2.tgz", + "integrity": "sha512-OVx6RWbfNOzBbfTvXoOkgZmaizdXDU/B/KbBjietXQoInSg/OSULjOavXJzL51XWFkbefqkOvbeE07DfvW6FkQ==", "dependencies": { - "bson": "^5.4.0", + "bson": "^5.5.0", "kareem": "2.5.1", "mongodb": "5.9.0", "mpath": "0.9.0", @@ -4079,9 +4129,9 @@ } }, "node_modules/resolve": { - "version": "1.22.6", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", - "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "dependencies": { "is-core-module": "^2.13.0", @@ -4781,6 +4831,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "5.25.3", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", + "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==" + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/package.json b/package.json index cb7d8fd..be72ba5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "lounasbotti", "type": "module", - "version": "1.8.0", + "version": "1.8.1", "private": true, "description": "Slack bot for retrieving lunch menus of local restaurants. Very much WIP and not meant for public use.", "main": "./dist/server.js", @@ -17,7 +17,7 @@ "test": "echo \"Error: no test specified\" && exit 1", "build": "tsc", "lint": "eslint . --no-fix --max-warnings 0 --rule \"linebreak-style:off\"", - "sentry:sourcemaps": "sentry-cli sourcemaps inject ./dist && sentry-cli sourcemaps upload ./dist" + "sentry:sourcemaps": "sentry-cli sourcemaps inject ./dist && sentry-cli sourcemaps upload --release=%npm_package_version% ./dist" }, "keywords": [ "bot", @@ -41,6 +41,7 @@ "@typescript-eslint/eslint-plugin": "^5.39.0", "@typescript-eslint/parser": "^5.39.0", "eslint": "^8.45.0", + "eslint-config-alloy": "^5.1.2", "eslint-import-resolver-typescript": "^3.3.0", "eslint-plugin-import": "^2.27.5", "ts-node": "^10.9.1", diff --git a/resources/manifest.yml b/resources/manifest.yml index d11dc94..fe7ca1a 100644 --- a/resources/manifest.yml +++ b/resources/manifest.yml @@ -31,11 +31,13 @@ oauth_config: scopes: bot: - channels:history + - channels:join - chat:write + - chat:write.public - commands - im:history - reactions:write - - chat:write.public + - channels:manage settings: event_subscriptions: request_url: https://lounasbotti-disec.fly.dev/slack/events diff --git a/src/AdminEvents.ts b/src/AdminEvents.ts index e1a66fe..99012b3 100644 --- a/src/AdminEvents.ts +++ b/src/AdminEvents.ts @@ -1,5 +1,5 @@ -import bolt from "@slack/bolt"; -import { Settings } from "./model/Settings.js"; +import type bolt from "@slack/bolt"; +import type { Settings } from "./model/Settings.js"; const ANNOUNCE_REGEXP = /lounasbotti\sadmin\sannounce\s"((?:\w|\d){1,30})"\s"([^"]{1,2000})"/; diff --git a/src/BlockParsers.ts b/src/BlockParsers.ts index b0ccb9e..6d36c26 100644 --- a/src/BlockParsers.ts +++ b/src/BlockParsers.ts @@ -1,8 +1,9 @@ import { Bits, BlockCollection, Blocks, Elements, HomeTab, Md, setIfTruthy, user } from "slack-block-builder"; -import { SlackBlockDto, SlackHomeTabDto } from "slack-block-builder/dist/internal"; +import type { SlackBlockDto, SlackHomeTabDto } from "slack-block-builder/dist/internal"; -import { LounasDataProvider, LounasResponse } from "./model/dataProviders/LounasDataProvider.js"; -import { RestaurantNameMap, Settings } from "./model/Settings.js"; +import type { LounasResponse } from "./model/dataProviders/LounasDataProvider.js"; +import type { Settings } from "./model/Settings.js"; +import { RestaurantNameMap } from "./model/Settings.js"; export default class BlockParsers { private static limitVotesToOneOptionBit = Bits.Option({ text: "Salli käyttäjän äänestää vain yhtä vaihtoehtoa" }); @@ -42,19 +43,19 @@ export default class BlockParsers { ]; } - public static parseHomeTabView(data: { settings: Settings, version: string, userId: string}): Readonly { + public static parseHomeTabView(data: { settings: Settings, userId: string}): Readonly { const debugInformation: string[] = [ data.settings.configSource ? `Config loaded from ${data.settings.configSource}` : null, - `Data provider: ${(data.settings.dataProvider as LounasDataProvider).id} (${(data.settings.dataProvider as LounasDataProvider).baseUrl})`, + `Data provider: ${data.settings.dataProvider.id} (${data.settings.dataProvider.baseUrl})`, `[LounasEmoji] ${data.settings.emojiRules?.size ? `${data.settings.emojiRules?.size} regular expressions successfully loaded` : "No rules loaded"}`, global.LOUNASBOTTI_JOBS.cacheClearing ? `Cached data will be cleared at ${global.LOUNASBOTTI_JOBS.cacheClearing.nextInvocation().toLocaleString("en-US")}` : null, - global.LOUNASBOTTI_JOBS.prefetch ? `Automatic posting to subscribed channels will next occur at ${global.LOUNASBOTTI_JOBS.prefetch.nextInvocation().toLocaleString("en-US")}` : null, + global.LOUNASBOTTI_JOBS.subscriptions ? `Automatic posting to subscribed channels will next occur at ${global.LOUNASBOTTI_JOBS.subscriptions.nextInvocation().toLocaleString("en-US")}` : null, `${(data.settings.subscribedChannels || []).length} channel subscription(s)` ].filter(Boolean) as string[]; return HomeTab() .blocks( - Blocks.Header({ text: `Lounasbotti V${data.version}` }).end(), + Blocks.Header({ text: `Lounasbotti ${global.LOUNASBOTTI_VERSION}` }).end(), Blocks.Section({ text: Md.italic("By ") }).end(), Blocks.Divider().end(), diff --git a/src/BotActions.ts b/src/BotActions.ts index 554e3b0..2cbb880 100644 --- a/src/BotActions.ts +++ b/src/BotActions.ts @@ -1,5 +1,6 @@ -import bolt, { BlockAction, CheckboxesAction, PlainTextInputAction } from "@slack/bolt"; -import { Settings } from "./model/Settings.js"; +import type { BlockAction, CheckboxesAction, PlainTextInputAction } from "@slack/bolt"; +import type bolt from "@slack/bolt"; +import type { Settings } from "./model/Settings.js"; import * as SettingsRepository from "./model/SettingsRepository.js"; export default function(app: bolt.App, settings: Settings) { diff --git a/src/BotCommands.ts b/src/BotCommands.ts index e6235ae..90e9d8c 100644 --- a/src/BotCommands.ts +++ b/src/BotCommands.ts @@ -1,6 +1,6 @@ -import bolt from "@slack/bolt"; +import type bolt from "@slack/bolt"; import { Md } from "slack-block-builder"; -import { Settings } from "./model/Settings"; +import type { Settings } from "./model/Settings"; import * as SettingsRepository from "./model/SettingsRepository.js"; export default function(app: bolt.App, settings: Settings) { @@ -53,7 +53,16 @@ export default function(app: bolt.App, settings: Settings) { return; } - // TODO: Check rights to channel + try { + await args.client.conversations.join({ channel: args.body.channel_id }); + } catch (error) { + console.error(error); + args.respond({ + response_type: "ephemeral", + text: "Error subscribing to channel. Lounasbotti could not join this channel. Please contact support." + }); + return; + } SettingsRepository.update({ instanceId: settings.instanceId, @@ -65,7 +74,7 @@ export default function(app: bolt.App, settings: Settings) { console.info(`User ${args.body.user_id} (${args.body.user_name}) subscribed to channel ${args.body.channel_id}`); args.respond({ response_type: "in_channel", - text: `${Md.user(args.body.user_id)} subscribed Lounasbotti to this channel. Next automatic activation will happen at ${Md.codeInline(global.LOUNASBOTTI_JOBS.prefetch.nextInvocation().toLocaleString("en-US"))}. Use ${Md.codeInline("/lounasbotti unsubscribe")} to unsubscribe.` + text: `${Md.user(args.body.user_id)} subscribed Lounasbotti to this channel. Next automatic activation will happen at ${Md.codeInline(global.LOUNASBOTTI_JOBS.subscriptions.nextInvocation().toLocaleString("en-US"))}. Use ${Md.codeInline("/lounasbotti unsubscribe")} to unsubscribe.` }); }).catch(error => { console.error(error); @@ -99,6 +108,8 @@ export default function(app: bolt.App, settings: Settings) { response_type: "in_channel", text: `${Md.user(args.body.user_id)} unsubscribed Lounasbotti from this channel. Use ${Md.codeInline("/lounasbotti subscribe")} to subscribe again.` }); + + args.client.conversations.leave({ channel: args.body.channel_id }); }).catch(error => { console.error(error); args.respond({ diff --git a/src/BotEvents.ts b/src/BotEvents.ts index 165c5c1..a72627c 100644 --- a/src/BotEvents.ts +++ b/src/BotEvents.ts @@ -1,14 +1,16 @@ -import bolt, {Button, GenericMessageEvent, SectionBlock, SlackCommandMiddlewareArgs } from "@slack/bolt"; +import type {Button, GenericMessageEvent, SectionBlock, SlackCommandMiddlewareArgs } from "@slack/bolt"; +import type bolt from "@slack/bolt"; import * as Utils from "./Utils.js"; -import { LounasDataProvider, LounasResponse } from "./model/dataProviders/LounasDataProvider.js"; -import { Restaurant, Settings } from "./model/Settings.js"; +import type { LounasResponse } from "./model/dataProviders/LounasDataProvider.js"; +import type { Settings } from "./model/Settings.js"; +import { Restaurant } from "./model/Settings.js"; import * as LounasRepository from "./model/LounasRepository.js"; import BlockParsers from "./BlockParsers.js"; import { BlockCollection, Blocks, Md } from "slack-block-builder"; -import { StringIndexed } from "@slack/bolt/dist/types/helpers.js"; +import type { StringIndexed } from "@slack/bolt/dist/types/helpers.js"; import { Range, scheduleJob } from "node-schedule"; type MessageMiddlewareArgs = bolt.SlackEventMiddlewareArgs<"message"> & bolt.AllMiddlewareArgs; @@ -22,8 +24,8 @@ const toBeTruncated: { channel: string, ts: string }[] = []; const lounasCache: Record = {}; // eslint-disable-next-line max-params -const initEvents = (app: bolt.App, settings: Settings, dataProvider: LounasDataProvider, version: string): void => { - global.LOUNASBOTTI_JOBS.prefetch = scheduleJob({ +const initEvents = (app: bolt.App, settings: Settings): void => { + global.LOUNASBOTTI_JOBS.subscriptions = scheduleJob({ second: 30, minute: 30, hour: 10, @@ -57,7 +59,7 @@ const initEvents = (app: bolt.App, settings: Settings, dataProvider: LounasDataP app.event("app_home_opened", async args => { args.client.views.publish({ user_id: args.event.user, - view: BlockParsers.parseHomeTabView({settings, version, userId: args.event.user}) + view: BlockParsers.parseHomeTabView({settings, userId: args.event.user}) }); }); @@ -86,7 +88,7 @@ const initEvents = (app: bolt.App, settings: Settings, dataProvider: LounasDataP throw new Error("No blocks found in message body"); } - const cachedData = await getDataAndCache(dataProvider, settings, false, false, Restaurant[actionValue as Restaurant]); + const cachedData = await getDataAndCache(settings, false, false, Restaurant[actionValue as Restaurant]); const lounasResponse: LounasResponse | undefined = cachedData.data.find(lounasResponse => lounasResponse.restaurant === actionValue); if (!lounasResponse) { throw new Error(`Could not find data for restaurant ${actionValue}`); @@ -242,7 +244,7 @@ const initEvents = (app: bolt.App, settings: Settings, dataProvider: LounasDataP }); } - const cachedData = await getDataAndCache(dataProvider, settings, true, isTomorrowRequest); + const cachedData = await getDataAndCache(settings, true, isTomorrowRequest); let requester: string; if (isAutomatic) { @@ -308,6 +310,7 @@ const initEvents = (app: bolt.App, settings: Settings, dataProvider: LounasDataP export { initEvents }; +// eslint-disable-next-line max-params function handleMainTriggerResponse(response: any, settings: Settings, channel: string, cachedData: LounasResponse[], isTomorrowRequest: boolean) { if (response.ok && response.ts) { if (!settings.debug?.noDb && !isTomorrowRequest) { @@ -350,7 +353,7 @@ function truncateMessage(app: bolt.App): void { } // eslint-disable-next-line max-params -async function getDataAndCache(dataProvider: LounasDataProvider, settings: Settings, defaultOnly: boolean, tomorrowRequest = false, singleRestaurant: Restaurant | null = null): Promise<{ data: LounasResponse[], blocks: (bolt.Block | bolt.KnownBlock)[] }> { +async function getDataAndCache(settings: Settings, defaultOnly: boolean, tomorrowRequest = false, singleRestaurant: Restaurant | null = null): Promise<{ data: LounasResponse[], blocks: (bolt.Block | bolt.KnownBlock)[] }> { try { const now = new Date(); const cacheIdentifier = `${now.getUTCDate()}${now.getUTCMonth()}${now.getUTCFullYear()}${tomorrowRequest}`; @@ -380,7 +383,7 @@ async function getDataAndCache(dataProvider: LounasDataProvider, settings: Setti } // Fetch restaurants that are missing from the cache - allData.push(...(await dataProvider.getData(allRestaurants.filter(restaurant => !allData.find(data => data.restaurant === restaurant)), tomorrowRequest))); + allData.push(...(await settings.dataProvider.getData(allRestaurants.filter(restaurant => !allData.find(data => data.restaurant === restaurant)), tomorrowRequest))); const hasDate = allData.filter(lounas => lounas.date); const header = `Lounaslistat${hasDate.length ? ` (${hasDate[0].date})` : ""}`; diff --git a/src/Utils.ts b/src/Utils.ts index 2809df7..1eb12fa 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -1,5 +1,6 @@ import { deserialize, serialize } from "v8"; -import fetch, { RequestInfo, RequestInit, Response } from "node-fetch"; +import type { RequestInfo, RequestInit, Response } from "node-fetch"; +import fetch from "node-fetch"; const BR_EXP = //i; @@ -83,7 +84,7 @@ const fetchWithTimeout = (url: RequestInfo, init: RequestInit = {}, allowRetry = return fetch(url, {...init, signal: controller.signal}).catch(error => { console.error(error); if (allowRetry) { - return new Promise(resolve => setTimeout(resolve, 2000)).then(() => fetchWithTimeout(url, init, false)); + return new Promise(resolve => { setTimeout(resolve, 2000); }).then(() => fetchWithTimeout(url, init, false)); } throw error; diff --git a/src/model/LounasRepository.ts b/src/model/LounasRepository.ts index 77ef7e6..769c268 100644 --- a/src/model/LounasRepository.ts +++ b/src/model/LounasRepository.ts @@ -1,5 +1,6 @@ -import mongoose, { UpdateQuery } from "mongoose"; -import { Restaurant } from "./Settings"; +import type { UpdateQuery } from "mongoose"; +import mongoose from "mongoose"; +import type { Restaurant } from "./Settings"; type LounasMessageEntry = { instanceId: string, diff --git a/src/model/Settings.ts b/src/model/Settings.ts index 9939af9..5bc11b1 100644 --- a/src/model/Settings.ts +++ b/src/model/Settings.ts @@ -1,6 +1,6 @@ import { promises as fs } from "fs"; -import { LounasDataProvider } from "./dataProviders/LounasDataProvider.js"; +import type { LounasDataProvider } from "./dataProviders/LounasDataProvider.js"; import * as Utils from "../Utils.js"; import RuokapaikkaFiDataProvider from "./dataProviders/RuokapaikkaFiDataProvider.js"; import MockDataProvider from "./dataProviders/MockDataProvider.js"; @@ -8,7 +8,6 @@ import * as SettingsRepository from "./SettingsRepository.js"; class Settings { public instanceId: string; - public dataProvider: LounasDataProvider | "self" = "self"; public triggerRegExp: RegExp; public defaultRestaurants: Restaurant[]; public additionalRestaurants?: Restaurant[]; @@ -31,15 +30,17 @@ class Settings { public limitToOneVotePerUser = false; public subscribedChannels?: string[] | undefined; - constructor(json: any, VERSION: string) { + public _dataProvider: LounasDataProvider | "self" = "self"; + + constructor(json: any) { this.instanceId = Utils.requireNonNullOrUndefined(json.instanceId, "Parameter instanceId is required"); switch (Utils.requireNonNullOrUndefined(json.dataProvider, "Parameter dataProvider is required")) { case "ruokapaikkaFi": - this.dataProvider = new RuokapaikkaFiDataProvider(this, VERSION); + this._dataProvider = new RuokapaikkaFiDataProvider(this); break; case "mock": - this.dataProvider = new MockDataProvider(this); + this._dataProvider = new MockDataProvider(this); break; default: throw new Error(`Unknown data provider ${json.dataProvider}`); @@ -119,6 +120,14 @@ class Settings { this.debug = json.debug; } } + + public get dataProvider(): LounasDataProvider { + if (typeof this._dataProvider === "string") { + throw new Error(); + } + + return this._dataProvider; + } } type InstanceSettings = { @@ -160,12 +169,12 @@ const RestaurantNameMap: Record = { kivijalka: "Ravintola Kivijalka" }; -const readAndParseSettings = async (VERSION: string, config?: string | undefined, configURLs?: URL[] | undefined): Promise => { +const readAndParseSettings = async (config?: string | undefined, configURLs?: URL[] | undefined): Promise => { let json: any; if (configURLs?.length) { for (const url of configURLs) { - json = await tryToReadSettingsFromURL(url, VERSION); + json = await tryToReadSettingsFromURL(url); if (json) {break;} } @@ -182,7 +191,7 @@ const readAndParseSettings = async (VERSION: string, config?: string | undefined console.info(`Using configuration from ${json.configSource}`); - return new Settings(json, VERSION); + return new Settings(json); }; const readInstanceSettings = (settings: Settings): void => { @@ -201,12 +210,12 @@ const readInstanceSettings = (settings: Settings): void => { export { Settings, InstanceSettings, Restaurant, RestaurantNameMap, readAndParseSettings, readInstanceSettings }; -async function tryToReadSettingsFromURL(url: URL, VERSION: string): Promise { +async function tryToReadSettingsFromURL(url: URL): Promise { try { const response = await Utils.fetchWithTimeout(url.toString(), { method: "GET", headers: { - "User-Agent": `Mozilla/5.0 (compatible; Lounasbotti/${VERSION};)`, + "User-Agent": `Mozilla/5.0 (compatible; Lounasbotti/${global.LOUNASBOTTI_VERSION};)`, Accept: "application/json" } }); diff --git a/src/model/SettingsRepository.ts b/src/model/SettingsRepository.ts index 3406ddd..a925742 100644 --- a/src/model/SettingsRepository.ts +++ b/src/model/SettingsRepository.ts @@ -1,5 +1,6 @@ -import mongoose, { UpdateQuery } from "mongoose"; -import { InstanceSettings } from "./Settings"; +import type { UpdateQuery } from "mongoose"; +import mongoose from "mongoose"; +import type { InstanceSettings } from "./Settings"; const instanceSettingsSchema = new mongoose.Schema({ instanceId: String, diff --git a/src/model/dataProviders/LounasDataProvider.ts b/src/model/dataProviders/LounasDataProvider.ts index cc5944e..d6d4618 100644 --- a/src/model/dataProviders/LounasDataProvider.ts +++ b/src/model/dataProviders/LounasDataProvider.ts @@ -1,4 +1,4 @@ -import { Restaurant, Settings } from "../Settings.js"; +import type { Restaurant, Settings } from "../Settings.js"; interface LounasDataProvider { readonly id: string; diff --git a/src/model/dataProviders/MockDataProvider.ts b/src/model/dataProviders/MockDataProvider.ts index 11a5176..e160ed5 100644 --- a/src/model/dataProviders/MockDataProvider.ts +++ b/src/model/dataProviders/MockDataProvider.ts @@ -1,5 +1,5 @@ -import { LounasDataProvider, LounasResponse } from "./LounasDataProvider"; -import { Restaurant, Settings } from "../Settings"; +import type { LounasDataProvider, LounasResponse } from "./LounasDataProvider"; +import type { Restaurant, Settings } from "../Settings"; import * as Utils from "../../Utils.js"; class MockDataProvider implements LounasDataProvider { diff --git a/src/model/dataProviders/RuokapaikkaFiDataProvider.ts b/src/model/dataProviders/RuokapaikkaFiDataProvider.ts index 2ef6e5f..3cc4a24 100644 --- a/src/model/dataProviders/RuokapaikkaFiDataProvider.ts +++ b/src/model/dataProviders/RuokapaikkaFiDataProvider.ts @@ -1,6 +1,7 @@ import * as Utils from "../../Utils.js"; -import { LounasDataProvider, LounasResponse } from "./LounasDataProvider.js"; -import { Restaurant, RestaurantNameMap, Settings } from "../Settings.js"; +import type { LounasDataProvider, LounasResponse } from "./LounasDataProvider.js"; +import type { Settings } from "../Settings.js"; +import { Restaurant, RestaurantNameMap } from "../Settings.js"; import TalliDataProvider from "./TalliDataProvider.js"; import VaihdaDataProvider from "./VaihaDataProvider.js"; @@ -9,14 +10,12 @@ class RuokapaikkaFiDataProvider implements LounasDataProvider { readonly baseUrl: string = "https://www.ruokapaikka.fi/resources/lunch/pois"; readonly settings: Settings; - readonly VERSION: string; readonly HEADER_REGEXP = /Lounas\s\d{1,2}\.\d{1,2}\./; readonly EXTRA_SPACES_REGEXP = /\s{5,}/g; - public constructor(settings: Settings, VERSION: string) { + public constructor(settings: Settings) { this.settings = settings; - this.VERSION = VERSION; } public async getData(restaurants: Restaurant[], tomorrowRequest = false): Promise { @@ -50,7 +49,7 @@ class RuokapaikkaFiDataProvider implements LounasDataProvider { const response = await Utils.fetchWithTimeout(url.toString(), { method: "GET", headers: { - "User-Agent": `Mozilla/5.0 (compatible; Lounasbotti/${this.VERSION}; +${this.settings.gitUrl})` + "User-Agent": `Mozilla/5.0 (compatible; Lounasbotti/${global.LOUNASBOTTI_VERSION}; +${this.settings.gitUrl})` } }); @@ -87,13 +86,13 @@ class RuokapaikkaFiDataProvider implements LounasDataProvider { const dataBlock = json.find(block => block.name === RestaurantNameMap[restaurant]); if (!dataBlock) { if (restaurant === Restaurant.talli) { - const talliResponseArr = await new TalliDataProvider(this.settings, this.VERSION).getData([Restaurant.talli], tomorrowRequest); + const talliResponseArr = await new TalliDataProvider(this.settings).getData([Restaurant.talli], tomorrowRequest); if (talliResponseArr[0]?.items?.length) { return talliResponseArr[0]; } } else if (restaurant === Restaurant.savo) { - const responseArr = await new VaihdaDataProvider(this.settings, this.VERSION).getData([Restaurant.savo], tomorrowRequest); + const responseArr = await new VaihdaDataProvider(this.settings).getData([Restaurant.savo], tomorrowRequest); if (responseArr[0]?.items?.length) { return responseArr[0]; } diff --git a/src/model/dataProviders/TalliDataProvider.ts b/src/model/dataProviders/TalliDataProvider.ts index 60f5f9a..f35f0dd 100644 --- a/src/model/dataProviders/TalliDataProvider.ts +++ b/src/model/dataProviders/TalliDataProvider.ts @@ -1,7 +1,8 @@ import * as cheerio from "cheerio"; -import { LounasDataProvider, LounasResponse } from "./LounasDataProvider.js"; -import { Restaurant, Settings } from "../Settings.js"; +import type { LounasDataProvider, LounasResponse } from "./LounasDataProvider.js"; +import type { Settings } from "../Settings.js"; +import { Restaurant } from "../Settings.js"; import * as Utils from "../../Utils.js"; class TalliDataProvider implements LounasDataProvider { @@ -9,11 +10,9 @@ class TalliDataProvider implements LounasDataProvider { readonly baseUrl: string = "https://www.xamkravintolat.fi/tallin-lounaslista/"; readonly settings: Settings; - readonly VERSION: string; - public constructor(settings: Settings, VERSION: string) { + public constructor(settings: Settings) { this.settings = settings; - this.VERSION = VERSION; } public async getData(restaurants: Restaurant[], tomorrowRequest = false): Promise { @@ -27,7 +26,7 @@ class TalliDataProvider implements LounasDataProvider { const response = await Utils.fetchWithTimeout(this.baseUrl, { method: "GET", headers: { - "User-Agent": `Mozilla/5.0 (compatible; Lounasbotti/${this.VERSION}; +${this.settings.gitUrl})` + "User-Agent": `Mozilla/5.0 (compatible; Lounasbotti/${global.LOUNASBOTTI_VERSION}; +${this.settings.gitUrl})` } }); diff --git a/src/model/dataProviders/VaihaDataProvider.ts b/src/model/dataProviders/VaihaDataProvider.ts index a8cf7bd..3934095 100644 --- a/src/model/dataProviders/VaihaDataProvider.ts +++ b/src/model/dataProviders/VaihaDataProvider.ts @@ -1,7 +1,8 @@ import * as cheerio from "cheerio"; -import { LounasDataProvider, LounasResponse } from "./LounasDataProvider"; -import { Restaurant, Settings } from "../Settings.js"; +import type { LounasDataProvider, LounasResponse } from "./LounasDataProvider"; +import type { Settings } from "../Settings.js"; +import { Restaurant } from "../Settings.js"; import * as Utils from "../../Utils.js"; class VaihdaDataProvider implements LounasDataProvider { @@ -9,15 +10,13 @@ class VaihdaDataProvider implements LounasDataProvider { readonly baseUrl: string = "https://www.vaiha.fi/kaikki-uutiset/vaiha-lounas"; readonly settings: Settings; - readonly VERSION: string; readonly supportedRestaurants = [ Restaurant.savo ]; - public constructor(settings: Settings, VERSION: string) { + public constructor(settings: Settings) { this.settings = settings; - this.VERSION = VERSION; } public async getData(restaurants: Restaurant[], tomorrowRequest = false): Promise { @@ -31,7 +30,7 @@ class VaihdaDataProvider implements LounasDataProvider { const response = await Utils.fetchWithTimeout(this.baseUrl, { method: "GET", headers: { - "User-Agent": `Mozilla/5.0 (compatible; Lounasbotti/${this.VERSION}; +${this.settings.gitUrl})` + "User-Agent": `Mozilla/5.0 (compatible; Lounasbotti/${global.LOUNASBOTTI_VERSION}; +${this.settings.gitUrl})` } }); diff --git a/src/server.ts b/src/server.ts index cc81df3..540cfab 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,11 +1,16 @@ import dotenv from "dotenv"; dotenv.config(); +// Global +global.LOUNASBOTTI_JOBS = {}; +global.LOUNASBOTTI_VERSION = process.env["npm_package_version"] ?? "1.8.1"; + import * as Sentry from "@sentry/node"; import { CaptureConsole } from "@sentry/integrations"; if (process.env.SENTRY_DSN) { Sentry.init({ dsn: process.env.SENTRY_DSN, + release: global.LOUNASBOTTI_VERSION, integrations: [ new CaptureConsole({ levels: ["error"] @@ -17,7 +22,7 @@ if (process.env.SENTRY_DSN) { console.warn("SENTRY_DSN not available. Sentry not enabled."); } -import { AddressInfo } from "net"; +import type { AddressInfo } from "net"; import bolt from "@slack/bolt"; @@ -30,11 +35,7 @@ import AdminEvents from "./AdminEvents.js"; import { decodeBase64 } from "./Utils.js"; import BotCommands from "./BotCommands.js"; -// Global -global.LOUNASBOTTI_JOBS = {}; - -const VERSION = process.env["npm_package_version"] ?? "1.8.0"; -console.info(`Lounasbotti v${VERSION} server starting...`); +console.info(`Lounasbotti v${global.LOUNASBOTTI_VERSION} server starting...`); if (!process.env["SLACK_SECRET"] || !process.env["SLACK_TOKEN"] @@ -46,7 +47,7 @@ if (!process.env["SLACK_SECRET"] const socketMode: boolean = process.env["SLACK_SOCKET"] as unknown as boolean || false; const configURLs: URL[] | undefined = process.env["SLACK_CONFIG_URL"]?.split(";").map(s => new URL(s)); -readAndParseSettings(VERSION, process.env["SLACK_CONFIG_NAME"], configURLs).then(settings => { +readAndParseSettings(process.env["SLACK_CONFIG_NAME"], configURLs).then(settings => { const { App } = bolt; if (!settings.debug?.noDb) { @@ -80,13 +81,9 @@ readAndParseSettings(VERSION, process.env["SLACK_CONFIG_NAME"], configURLs).then ]; const app = new App(appOptions); - - if (typeof settings.dataProvider === "string") { - throw new Error("Incorrect dataProvider"); - } BotCommands(app, settings); - BotEvents.initEvents(app, settings, settings.dataProvider, VERSION); + BotEvents.initEvents(app, settings); AdminEvents(app, settings); BotActions(app, settings); diff --git a/src/types.d.ts b/src/types.d.ts index 33ee327..0294f6b 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -1,6 +1,8 @@ +/* eslint-disable no-inner-declarations */ /* eslint-disable no-var */ -import { Job } from "node-schedule"; +import type { Job } from "node-schedule"; declare global { var LOUNASBOTTI_JOBS: Record; + var LOUNASBOTTI_VERSION: string; } \ No newline at end of file