From cc82db447bbd5c7f75f129491d93d04feac9edb8 Mon Sep 17 00:00:00 2001 From: zkldi <20380519+zkldi@users.noreply.github.com> Date: Sun, 26 Jun 2022 16:28:11 +0100 Subject: [PATCH] style: migrate to cadence --- common/.eslintignore | 3 +- common/.eslintrc | 77 +- common/package.json | 11 +- common/pnpm-lock.yaml | 1089 ++++++++++++++++++++------- common/src/config/config.test.ts | 3 +- common/src/config/config.ts | 60 +- common/src/config/static-config.ts | 14 +- common/src/constants/game.ts | 244 +++--- common/src/constants/permissions.ts | 2 +- common/src/game-classes.ts | 29 +- common/src/index.test.ts | 3 +- common/src/legacy/legacy-config.ts | 539 ------------- common/src/lib/esd.test.ts | 10 +- common/src/lib/esd.ts | 29 +- common/src/lib/schemas.ts | 141 ++-- common/src/types.ts | 598 +++++++-------- common/src/utils/util.ts | 31 +- common/src/webhooks.ts | 10 +- common/tsconfig.json | 4 +- 19 files changed, 1442 insertions(+), 1455 deletions(-) delete mode 100644 common/src/legacy/legacy-config.ts diff --git a/common/.eslintignore b/common/.eslintignore index df5460fcc..1642c05af 100644 --- a/common/.eslintignore +++ b/common/.eslintignore @@ -1,3 +1,2 @@ node_modules -js -scripts \ No newline at end of file +js \ No newline at end of file diff --git a/common/.eslintrc b/common/.eslintrc index 5323de375..661751a32 100644 --- a/common/.eslintrc +++ b/common/.eslintrc @@ -1,59 +1,34 @@ { - "root": true, - "parser": "@typescript-eslint/parser", "plugins": [ - "@typescript-eslint" + "@typescript-eslint", + "import", + "cadence" ], - "env": { - "node": true - }, "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "plugin:prettier/recommended" + "plugin:cadence/recommended" ], "rules": { - "prettier/prettier": [ - "error", - { - "printWidth": 100, - "tabWidth": 4, - "semi": true, - "singleQuote": false, - "trailingComma": "es5", - "bracketSpacing": true, - "endOfLine": "auto", - "useTabs": true - } - ], - "@typescript-eslint/no-unused-vars": "error", - "@typescript-eslint/no-unused-expressions": "error", - "@typescript-eslint/no-extra-semi": "off", "@typescript-eslint/no-non-null-assertion": "off", - "no-unused-labels": "error", - "prefer-const": "error", - "eqeqeq": "error", - "no-eval": "error", - "no-var": "error", - "no-new-object": "error", - "quote-props": [ - "error", - "as-needed" - ], - "no-array-constructor": "error", - "prefer-template": "error", - "prefer-promise-reject-errors": "error", - "no-useless-escape": "error", - "no-loop-func": "error", - "prefer-rest-params": "error", - "default-param-last": "error", - "no-new-func": "error", - "arrow-body-style": "error", - "no-useless-constructor": "error", - "no-duplicate-imports": "error", - "dot-notation": "error", - "space-before-blocks": "error", - "no-prototype-builtins": "off", - "prefer-arrow-callback": "error" - } + "no-inline-comments": "off" + }, + "overrides": [ + { + "files": [ + "**/*.test.ts" + ], + "rules": { + // Our test files break these rules *all* the time, and there's + // no point refactoring. Our tests deliberately play with the + // dynamic nature of TS to more accurately test arbitrary input. + "@typescript-eslint/no-floating-promises": "off", + "@typescript-eslint/no-unsafe-member-access": "off", + "@typescript-eslint/no-unsafe-assignment": "off", + "@typescript-eslint/no-unsafe-return": "off", + "@typescript-eslint/no-unsafe-argument": "off", + "@typescript-eslint/no-unsafe-call": "off", + // we abuse this one for faking data, but we really shouldn't. + "@typescript-eslint/consistent-type-assertions": "warn" + } + } + ] } \ No newline at end of file diff --git a/common/package.json b/common/package.json index bce156a06..43741558e 100644 --- a/common/package.json +++ b/common/package.json @@ -9,19 +9,16 @@ "scripts": { "test": "tap", "build": "tsc", - "prepublish": "tsc" + "prepublish": "tsc", + "lint": "eslint . --ext .ts --fix" }, "author": "zkldi", "license": "MIT", "devDependencies": { "@types/node": "17.0.8", "@types/tap": "15.0.3", - "@typescript-eslint/eslint-plugin": "4.19.0", - "@typescript-eslint/parser": "4.19.0", - "eslint": "7.22.0", - "eslint-config-prettier": "8.1.0", - "eslint-plugin-prettier": "3.3.1", - "prettier": "2.2.1", + "eslint": "8", + "eslint-plugin-cadence": "0.0.3", "tap": "15.0.9", "ts-node": "10.0.0", "typescript": "4.6.3" diff --git a/common/pnpm-lock.yaml b/common/pnpm-lock.yaml index 0a34762c3..e6dc7bf60 100644 --- a/common/pnpm-lock.yaml +++ b/common/pnpm-lock.yaml @@ -5,12 +5,8 @@ specifiers: '@types/mongodb': 3.6.18 '@types/node': 17.0.8 '@types/tap': 15.0.3 - '@typescript-eslint/eslint-plugin': 4.19.0 - '@typescript-eslint/parser': 4.19.0 - eslint: 7.22.0 - eslint-config-prettier: 8.1.0 - eslint-plugin-prettier: 3.3.1 - prettier: 2.2.1 + eslint: '8' + eslint-plugin-cadence: 0.0.3 prudence: ^0.9.8 tap: 15.0.9 ts-node: 10.0.0 @@ -24,24 +20,14 @@ dependencies: devDependencies: '@types/node': 17.0.8 '@types/tap': 15.0.3 - '@typescript-eslint/eslint-plugin': 4.19.0_462b4cd37d11e0260fa1b0b776770dee - '@typescript-eslint/parser': 4.19.0_eslint@7.22.0+typescript@4.6.3 - eslint: 7.22.0 - eslint-config-prettier: 8.1.0_eslint@7.22.0 - eslint-plugin-prettier: 3.3.1_44b94358ac15c7c093df3d5421ccc811 - prettier: 2.2.1 + eslint: 8.18.0 + eslint-plugin-cadence: 0.0.3_eslint@8.18.0+typescript@4.6.3 tap: 15.0.9_ts-node@10.0.0+typescript@4.6.3 ts-node: 10.0.0_22ec373cc6e5c139fea80a5e1bbc5c61 typescript: 4.6.3 packages: - /@babel/code-frame/7.12.11: - resolution: {integrity: sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==} - dependencies: - '@babel/highlight': 7.14.5 - dev: true - /@babel/code-frame/7.14.5: resolution: {integrity: sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==} engines: {node: '>=6.9.0'} @@ -334,23 +320,38 @@ packages: to-fast-properties: 2.0.0 dev: true - /@eslint/eslintrc/0.4.0: - resolution: {integrity: sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==} - engines: {node: ^10.12.0 || >=12.0.0} + /@eslint/eslintrc/1.3.0: + resolution: {integrity: sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 - debug: 4.3.1 - espree: 7.3.1 - globals: 12.4.0 - ignore: 4.0.6 + debug: 4.3.4 + espree: 9.3.2 + globals: 13.15.0 + ignore: 5.2.0 import-fresh: 3.3.0 - js-yaml: 3.14.1 - minimatch: 3.0.4 + js-yaml: 4.1.0 + minimatch: 3.1.2 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color dev: true + /@humanwhocodes/config-array/0.9.5: + resolution: {integrity: sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 1.2.1 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/object-schema/1.2.1: + resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + dev: true + /@istanbuljs/load-nyc-config/1.1.0: resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} engines: {node: '>=8'} @@ -367,25 +368,25 @@ packages: engines: {node: '>=8'} dev: true - /@nodelib/fs.scandir/2.1.4: - resolution: {integrity: sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==} + /@nodelib/fs.scandir/2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} dependencies: - '@nodelib/fs.stat': 2.0.4 + '@nodelib/fs.stat': 2.0.5 run-parallel: 1.2.0 dev: true - /@nodelib/fs.stat/2.0.4: - resolution: {integrity: sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==} + /@nodelib/fs.stat/2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} dev: true - /@nodelib/fs.walk/1.2.6: - resolution: {integrity: sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==} + /@nodelib/fs.walk/1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} dependencies: - '@nodelib/fs.scandir': 2.1.4 - fastq: 1.11.0 + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.13.0 dev: true /@tsconfig/node10/1.0.8: @@ -418,8 +419,12 @@ packages: '@types/range-parser': 1.2.4 dev: false - /@types/json-schema/7.0.7: - resolution: {integrity: sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==} + /@types/json-schema/7.0.11: + resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} + dev: true + + /@types/json5/0.0.29: + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true /@types/mongodb/3.6.18: @@ -446,122 +451,142 @@ packages: '@types/node': 17.0.8 dev: true - /@typescript-eslint/eslint-plugin/4.19.0_462b4cd37d11e0260fa1b0b776770dee: - resolution: {integrity: sha512-CRQNQ0mC2Pa7VLwKFbrGVTArfdVDdefS+gTw0oC98vSI98IX5A8EVH4BzJ2FOB0YlCmm8Im36Elad/Jgtvveaw==} - engines: {node: ^10.12.0 || >=12.0.0} + /@typescript-eslint/eslint-plugin/5.22.0_3692bfa38c76dfb409a7f758aafdbd9d: + resolution: {integrity: sha512-YCiy5PUzpAeOPGQ7VSGDEY2NeYUV1B0swde2e0HzokRsHBYjSdF6DZ51OuRZxVPHx0032lXGLvOMls91D8FXlg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: - '@typescript-eslint/parser': ^4.0.0 - eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 + '@typescript-eslint/parser': ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/experimental-utils': 4.19.0_eslint@7.22.0+typescript@4.6.3 - '@typescript-eslint/parser': 4.19.0_eslint@7.22.0+typescript@4.6.3 - '@typescript-eslint/scope-manager': 4.19.0 - debug: 4.3.1 - eslint: 7.22.0 + '@typescript-eslint/parser': 5.22.0_eslint@8.18.0+typescript@4.6.3 + '@typescript-eslint/scope-manager': 5.22.0 + '@typescript-eslint/type-utils': 5.22.0_eslint@8.18.0+typescript@4.6.3 + '@typescript-eslint/utils': 5.22.0_eslint@8.18.0+typescript@4.6.3 + debug: 4.3.4 + eslint: 8.18.0 functional-red-black-tree: 1.0.1 - lodash: 4.17.21 - regexpp: 3.1.0 - semver: 7.3.5 + ignore: 5.2.0 + regexpp: 3.2.0 + semver: 7.3.7 tsutils: 3.21.0_typescript@4.6.3 typescript: 4.6.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/experimental-utils/4.19.0_eslint@7.22.0+typescript@4.6.3: - resolution: {integrity: sha512-9/23F1nnyzbHKuoTqFN1iXwN3bvOm/PRIXSBR3qFAYotK/0LveEOHr5JT1WZSzcD6BESl8kPOG3OoDRKO84bHA==} - engines: {node: ^10.12.0 || >=12.0.0} + /@typescript-eslint/parser/5.22.0_eslint@8.18.0+typescript@4.6.3: + resolution: {integrity: sha512-piwC4krUpRDqPaPbFaycN70KCP87+PC5WZmrWs+DlVOxxmF+zI6b6hETv7Quy4s9wbkV16ikMeZgXsvzwI3icQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 5.22.0 + '@typescript-eslint/types': 5.22.0 + '@typescript-eslint/typescript-estree': 5.22.0_typescript@4.6.3 + debug: 4.3.4 + eslint: 8.18.0 + typescript: 4.6.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager/5.22.0: + resolution: {integrity: sha512-yA9G5NJgV5esANJCO0oF15MkBO20mIskbZ8ijfmlKIvQKg0ynVKfHZ15/nhAJN5m8Jn3X5qkwriQCiUntC9AbA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.22.0 + '@typescript-eslint/visitor-keys': 5.22.0 + dev: true + + /@typescript-eslint/type-utils/5.22.0_eslint@8.18.0+typescript@4.6.3: + resolution: {integrity: sha512-iqfLZIsZhK2OEJ4cQ01xOq3NaCuG5FQRKyHicA3xhZxMgaxQazLUHbH/B2k9y5i7l3+o+B5ND9Mf1AWETeMISA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '*' + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true dependencies: - '@types/json-schema': 7.0.7 - '@typescript-eslint/scope-manager': 4.19.0 - '@typescript-eslint/types': 4.19.0 - '@typescript-eslint/typescript-estree': 4.19.0_typescript@4.6.3 - eslint: 7.22.0 + '@typescript-eslint/utils': 5.22.0_eslint@8.18.0+typescript@4.6.3 + debug: 4.3.4 + eslint: 8.18.0 + tsutils: 3.21.0_typescript@4.6.3 + typescript: 4.6.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types/5.22.0: + resolution: {integrity: sha512-T7owcXW4l0v7NTijmjGWwWf/1JqdlWiBzPqzAWhobxft0SiEvMJB56QXmeCQjrPuM8zEfGUKyPQr/L8+cFUBLw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@typescript-eslint/typescript-estree/5.22.0_typescript@4.6.3: + resolution: {integrity: sha512-EyBEQxvNjg80yinGE2xdhpDYm41so/1kOItl0qrjIiJ1kX/L/L8WWGmJg8ni6eG3DwqmOzDqOhe6763bF92nOw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 5.22.0 + '@typescript-eslint/visitor-keys': 5.22.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.3.7 + tsutils: 3.21.0_typescript@4.6.3 + typescript: 4.6.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils/5.22.0_eslint@8.18.0+typescript@4.6.3: + resolution: {integrity: sha512-HodsGb037iobrWSUMS7QH6Hl1kppikjA1ELiJlNSTYf/UdMEwzgj0WIp+lBNb6WZ3zTwb0tEz51j0Wee3iJ3wQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@types/json-schema': 7.0.11 + '@typescript-eslint/scope-manager': 5.22.0 + '@typescript-eslint/types': 5.22.0 + '@typescript-eslint/typescript-estree': 5.22.0_typescript@4.6.3 + eslint: 8.18.0 eslint-scope: 5.1.1 - eslint-utils: 2.1.0 + eslint-utils: 3.0.0_eslint@8.18.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/parser/4.19.0_eslint@7.22.0+typescript@4.6.3: - resolution: {integrity: sha512-/uabZjo2ZZhm66rdAu21HA8nQebl3lAIDcybUoOxoI7VbZBYavLIwtOOmykKCJy+Xq6Vw6ugkiwn8Js7D6wieA==} - engines: {node: ^10.12.0 || >=12.0.0} - peerDependencies: - eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true + /@typescript-eslint/visitor-keys/5.22.0: + resolution: {integrity: sha512-DbgTqn2Dv5RFWluG88tn0pP6Ex0ROF+dpDO1TNNZdRtLjUr6bdznjA6f/qNqJLjd2PgguAES2Zgxh/JzwzETDg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/scope-manager': 4.19.0 - '@typescript-eslint/types': 4.19.0 - '@typescript-eslint/typescript-estree': 4.19.0_typescript@4.6.3 - debug: 4.3.1 - eslint: 7.22.0 - typescript: 4.6.3 - transitivePeerDependencies: - - supports-color + '@typescript-eslint/types': 5.22.0 + eslint-visitor-keys: 3.3.0 dev: true - /@typescript-eslint/scope-manager/4.19.0: - resolution: {integrity: sha512-GGy4Ba/hLXwJXygkXqMzduqOMc+Na6LrJTZXJWVhRrSuZeXmu8TAnniQVKgj8uTRKe4igO2ysYzH+Np879G75g==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} - dependencies: - '@typescript-eslint/types': 4.19.0 - '@typescript-eslint/visitor-keys': 4.19.0 - dev: true - - /@typescript-eslint/types/4.19.0: - resolution: {integrity: sha512-A4iAlexVvd4IBsSTNxdvdepW0D4uR/fwxDrKUa+iEY9UWvGREu2ZyB8ylTENM1SH8F7bVC9ac9+si3LWNxcBuA==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} - dev: true - - /@typescript-eslint/typescript-estree/4.19.0_typescript@4.6.3: - resolution: {integrity: sha512-3xqArJ/A62smaQYRv2ZFyTA+XxGGWmlDYrsfZG68zJeNbeqRScnhf81rUVa6QG4UgzHnXw5VnMT5cg75dQGDkA==} - engines: {node: ^10.12.0 || >=12.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 4.19.0 - '@typescript-eslint/visitor-keys': 4.19.0 - debug: 4.3.1 - globby: 11.0.3 - is-glob: 4.0.1 - semver: 7.3.5 - tsutils: 3.21.0_typescript@4.6.3 - typescript: 4.6.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/visitor-keys/4.19.0: - resolution: {integrity: sha512-aGPS6kz//j7XLSlgpzU2SeTqHPsmRYxFztj2vPuMMFJXZudpRSehE3WCV+BaxwZFvfAqMoSd86TEuM0PQ59E/A==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} - dependencies: - '@typescript-eslint/types': 4.19.0 - eslint-visitor-keys: 2.0.0 - dev: true - - /acorn-jsx/5.3.1_acorn@7.4.1: - resolution: {integrity: sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==} + /acorn-jsx/5.3.2_acorn@8.7.1: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - acorn: 7.4.1 + acorn: 8.7.1 dev: true - /acorn/7.4.1: - resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + /acorn/8.7.1: + resolution: {integrity: sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==} engines: {node: '>=0.4.0'} hasBin: true dev: true @@ -583,20 +608,6 @@ packages: uri-js: 4.4.1 dev: true - /ajv/8.1.0: - resolution: {integrity: sha512-B/Sk2Ix7A36fs/ZkuGLIR86EdjbgR6fsAcbx9lOP/QBSXujDNbVmIS/U4Itz5k8fPFDeVZl/zQ/gJW4Jrq6XjQ==} - dependencies: - fast-deep-equal: 3.1.3 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - uri-js: 4.4.1 - dev: true - - /ansi-colors/4.1.1: - resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} - engines: {node: '>=6'} - dev: true - /ansi-regex/2.1.1: resolution: {integrity: sha1-w7M6te42DYbg5ijwRorn7yfWVN8=} engines: {node: '>=0.10.0'} @@ -612,6 +623,11 @@ packages: engines: {node: '>=8'} dev: true + /ansi-regex/5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + /ansi-styles/3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -655,11 +671,36 @@ packages: sprintf-js: 1.0.3 dev: true + /argparse/2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /array-includes/3.1.5: + resolution: {integrity: sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.1 + get-intrinsic: 1.1.2 + is-string: 1.0.7 + dev: true + /array-union/2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} dev: true + /array.prototype.flat/1.3.0: + resolution: {integrity: sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.1 + es-shim-unscopables: 1.0.0 + dev: true + /asn1/0.2.4: resolution: {integrity: sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==} dependencies: @@ -671,11 +712,6 @@ packages: engines: {node: '>=0.8'} dev: true - /astral-regex/2.0.0: - resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} - engines: {node: '>=8'} - dev: true - /async-hook-domain/2.0.3: resolution: {integrity: sha512-MadiLLDEZRZzZwcm0dgS+K99qXZ4H2saAUwUgwzFulbAkXrKi3AX5FvWS3FFTQtLMwrqcGqAJe6o12KrObejQA==} engines: {node: '>=10'} @@ -753,6 +789,13 @@ packages: write-file-atomic: 3.0.3 dev: true + /call-bind/1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.1.2 + dev: true + /caller-callsite/2.0.0: resolution: {integrity: sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=} engines: {node: '>=4'} @@ -935,6 +978,18 @@ packages: assert-plus: 1.0.0 dev: true + /debug/2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + dependencies: + ms: 2.0.0 + dev: true + + /debug/3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + dependencies: + ms: 2.1.2 + dev: true + /debug/4.3.1: resolution: {integrity: sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==} engines: {node: '>=6.0'} @@ -947,13 +1002,25 @@ packages: ms: 2.1.2 dev: true + /debug/4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + /decamelize/1.2.0: resolution: {integrity: sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=} engines: {node: '>=0.10.0'} dev: true /deep-is/0.1.3: - resolution: {integrity: sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=} + resolution: {integrity: sha512-GtxAN4HvBachZzm4OnWqc45ESpUCMwkYcsjnsPs23FwJbsO+k4t0k9bQCgOmzIlpHO28+WPK/KRbRk0DDHuuDw==} dev: true /default-require-extensions/3.0.0: @@ -963,6 +1030,14 @@ packages: strip-bom: 4.0.0 dev: true + /define-properties/1.1.4: + resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==} + engines: {node: '>= 0.4'} + dependencies: + has-property-descriptors: 1.0.0 + object-keys: 1.1.1 + dev: true + /delayed-stream/1.0.0: resolution: {integrity: sha1-3zrhmayt+31ECqrgsp4icrJOxhk=} engines: {node: '>=0.4.0'} @@ -980,6 +1055,13 @@ packages: path-type: 4.0.0 dev: true + /doctrine/2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + /doctrine/3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} @@ -1002,11 +1084,48 @@ packages: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: true - /enquirer/2.3.6: - resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} - engines: {node: '>=8.6'} + /es-abstract/1.20.1: + resolution: {integrity: sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==} + engines: {node: '>= 0.4'} dependencies: - ansi-colors: 4.1.1 + call-bind: 1.0.2 + es-to-primitive: 1.2.1 + function-bind: 1.1.1 + function.prototype.name: 1.1.5 + get-intrinsic: 1.1.2 + get-symbol-description: 1.0.0 + has: 1.0.3 + has-property-descriptors: 1.0.0 + has-symbols: 1.0.3 + internal-slot: 1.0.3 + is-callable: 1.2.4 + is-negative-zero: 2.0.2 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + is-string: 1.0.7 + is-weakref: 1.0.2 + object-inspect: 1.12.2 + object-keys: 1.1.1 + object.assign: 4.1.2 + regexp.prototype.flags: 1.4.3 + string.prototype.trimend: 1.0.5 + string.prototype.trimstart: 1.0.5 + unbox-primitive: 1.0.2 + dev: true + + /es-shim-unscopables/1.0.0: + resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} + dependencies: + has: 1.0.3 + dev: true + + /es-to-primitive/1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.4 + is-date-object: 1.0.5 + is-symbol: 1.0.4 dev: true /es6-error/4.1.1: @@ -1028,29 +1147,128 @@ packages: engines: {node: '>=8'} dev: true - /eslint-config-prettier/8.1.0_eslint@7.22.0: - resolution: {integrity: sha512-oKMhGv3ihGbCIimCAjqkdzx2Q+jthoqnXSP+d86M9tptwugycmTFdVR4IpLgq2c4SHifbwO90z2fQ8/Aio73yw==} + /escape-string-regexp/4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /eslint-config-prettier/8.5.0_eslint@8.18.0: + resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 7.22.0 + eslint: 8.18.0 dev: true - /eslint-plugin-prettier/3.3.1_44b94358ac15c7c093df3d5421ccc811: - resolution: {integrity: sha512-Rq3jkcFY8RYeQLgk2cCwuc0P7SEFwDravPhsJZOQ5N4YI4DSg50NyqJ/9gdZHzQlHf8MvafSesbNJCcP/FF6pQ==} + /eslint-import-resolver-node/0.3.6: + resolution: {integrity: sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==} + dependencies: + debug: 3.2.7 + resolve: 1.22.1 + dev: true + + /eslint-module-utils/2.7.3: + resolution: {integrity: sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==} + engines: {node: '>=4'} + dependencies: + debug: 3.2.7 + find-up: 2.1.0 + dev: true + + /eslint-plugin-cadence/0.0.3_eslint@8.18.0+typescript@4.6.3: + resolution: {integrity: sha512-RQz1d4wU2UZe3Ztt8UPCZffvxZFuL6WkleIxcR5yW3KTwilXOePjpmJR69989L2IIlN+JcKlPjtPPairUV1E9g==} + engines: {node: 12.x || 14.x || >= 16} + peerDependencies: + eslint: '>=8' + dependencies: + '@typescript-eslint/eslint-plugin': 5.22.0_3692bfa38c76dfb409a7f758aafdbd9d + '@typescript-eslint/parser': 5.22.0_eslint@8.18.0+typescript@4.6.3 + eslint: 8.18.0 + eslint-config-prettier: 8.5.0_eslint@8.18.0 + eslint-plugin-eslint-plugin: 4.1.0_eslint@8.18.0 + eslint-plugin-import: 2.26.0_eslint@8.18.0 + eslint-plugin-node: 11.1.0_eslint@8.18.0 + eslint-plugin-prettier: 4.0.0_ee517d95c7d3128de95595e9379dd540 + prettier: 2.6.2 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /eslint-plugin-es/3.0.1_eslint@8.18.0: + resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==} + engines: {node: '>=8.10.0'} + peerDependencies: + eslint: '>=4.19.1' + dependencies: + eslint: 8.18.0 + eslint-utils: 2.1.0 + regexpp: 3.2.0 + dev: true + + /eslint-plugin-eslint-plugin/4.1.0_eslint@8.18.0: + resolution: {integrity: sha512-QJVw+WYXJuG2469gx5G929bz7crfxySDlK1i569FkuT6dpeHDeP7MmDrKaswCx17snG25LRFD6wmVX+AO5x7Qg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + eslint: 8.18.0 + eslint-utils: 3.0.0_eslint@8.18.0 + estraverse: 5.2.0 + dev: true + + /eslint-plugin-import/2.26.0_eslint@8.18.0: + resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + dependencies: + array-includes: 3.1.5 + array.prototype.flat: 1.3.0 + debug: 2.6.9 + doctrine: 2.1.0 + eslint: 8.18.0 + eslint-import-resolver-node: 0.3.6 + eslint-module-utils: 2.7.3 + has: 1.0.3 + is-core-module: 2.9.0 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.values: 1.1.5 + resolve: 1.22.1 + tsconfig-paths: 3.14.1 + dev: true + + /eslint-plugin-node/11.1.0_eslint@8.18.0: + resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==} + engines: {node: '>=8.10.0'} + peerDependencies: + eslint: '>=5.16.0' + dependencies: + eslint: 8.18.0 + eslint-plugin-es: 3.0.1_eslint@8.18.0 + eslint-utils: 2.1.0 + ignore: 5.2.0 + minimatch: 3.1.2 + resolve: 1.22.1 + semver: 6.3.0 + dev: true + + /eslint-plugin-prettier/4.0.0_ee517d95c7d3128de95595e9379dd540: + resolution: {integrity: sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==} engines: {node: '>=6.0.0'} peerDependencies: - eslint: '>=5.0.0' + eslint: '>=7.28.0' eslint-config-prettier: '*' - prettier: '>=1.13.0' + prettier: '>=2.0.0' peerDependenciesMeta: eslint-config-prettier: optional: true dependencies: - eslint: 7.22.0 - eslint-config-prettier: 8.1.0_eslint@7.22.0 - prettier: 2.2.1 + eslint: 8.18.0 + eslint-config-prettier: 8.5.0_eslint@8.18.0 + prettier: 2.6.2 prettier-linter-helpers: 1.0.0 dev: true @@ -1062,6 +1280,14 @@ packages: estraverse: 4.3.0 dev: true + /eslint-scope/7.1.1: + resolution: {integrity: sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.2.0 + dev: true + /eslint-utils/2.1.0: resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} engines: {node: '>=6'} @@ -1069,6 +1295,16 @@ packages: eslint-visitor-keys: 1.3.0 dev: true + /eslint-utils/3.0.0_eslint@8.18.0: + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + dependencies: + eslint: 8.18.0 + eslint-visitor-keys: 2.0.0 + dev: true + /eslint-visitor-keys/1.3.0: resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} engines: {node: '>=4'} @@ -1079,59 +1315,62 @@ packages: engines: {node: '>=10'} dev: true - /eslint/7.22.0: - resolution: {integrity: sha512-3VawOtjSJUQiiqac8MQc+w457iGLfuNGLFn8JmF051tTKbh5/x/0vlcEj8OgDCaw7Ysa2Jn8paGshV7x2abKXg==} - engines: {node: ^10.12.0 || >=12.0.0} + /eslint-visitor-keys/3.3.0: + resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint/8.18.0: + resolution: {integrity: sha512-As1EfFMVk7Xc6/CvhssHUjsAQSkpfXvUGMFC3ce8JDe6WvqCgRrLOBQbVpsBFr1X1V+RACOadnzVvcUS5ni2bA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@babel/code-frame': 7.12.11 - '@eslint/eslintrc': 0.4.0 + '@eslint/eslintrc': 1.3.0 + '@humanwhocodes/config-array': 0.9.5 ajv: 6.12.6 chalk: 4.1.1 cross-spawn: 7.0.3 - debug: 4.3.1 + debug: 4.3.4 doctrine: 3.0.0 - enquirer: 2.3.6 - eslint-scope: 5.1.1 - eslint-utils: 2.1.0 - eslint-visitor-keys: 2.0.0 - espree: 7.3.1 + escape-string-regexp: 4.0.0 + eslint-scope: 7.1.1 + eslint-utils: 3.0.0_eslint@8.18.0 + eslint-visitor-keys: 3.3.0 + espree: 9.3.2 esquery: 1.4.0 esutils: 2.0.3 + 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.8.0 - ignore: 4.0.6 + glob-parent: 6.0.2 + globals: 13.15.0 + ignore: 5.2.0 import-fresh: 3.3.0 imurmurhash: 0.1.4 is-glob: 4.0.1 - js-yaml: 3.14.1 + js-yaml: 4.1.0 json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 - lodash: 4.17.21 - minimatch: 3.0.4 + lodash.merge: 4.6.2 + minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.1 - progress: 2.0.3 - regexpp: 3.1.0 - semver: 7.3.5 - strip-ansi: 6.0.0 + regexpp: 3.2.0 + strip-ansi: 6.0.1 strip-json-comments: 3.1.1 - table: 6.5.1 text-table: 0.2.0 v8-compile-cache: 2.3.0 transitivePeerDependencies: - supports-color dev: true - /espree/7.3.1: - resolution: {integrity: sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==} - engines: {node: ^10.12.0 || >=12.0.0} + /espree/9.3.2: + resolution: {integrity: sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - acorn: 7.4.1 - acorn-jsx: 5.3.1_acorn@7.4.1 - eslint-visitor-keys: 1.3.0 + acorn: 8.7.1 + acorn-jsx: 5.3.2_acorn@8.7.1 + eslint-visitor-keys: 3.3.0 dev: true /esprima/4.0.1: @@ -1190,16 +1429,15 @@ packages: resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==} dev: true - /fast-glob/3.2.5: - resolution: {integrity: sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==} - engines: {node: '>=8'} + /fast-glob/3.2.11: + resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==} + engines: {node: '>=8.6.0'} dependencies: - '@nodelib/fs.stat': 2.0.4 - '@nodelib/fs.walk': 1.2.6 + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 - micromatch: 4.0.4 - picomatch: 2.3.0 + micromatch: 4.0.5 dev: true /fast-json-stable-stringify/2.1.0: @@ -1207,11 +1445,11 @@ packages: dev: true /fast-levenshtein/2.0.6: - resolution: {integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=} + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} dev: true - /fastq/1.11.0: - resolution: {integrity: sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==} + /fastq/1.13.0: + resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} dependencies: reusify: 1.0.4 dev: true @@ -1239,6 +1477,13 @@ packages: pkg-dir: 4.2.0 dev: true + /find-up/2.1.0: + resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} + engines: {node: '>=4'} + dependencies: + locate-path: 2.0.0 + dev: true + /find-up/4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} @@ -1304,14 +1549,32 @@ packages: dev: true optional: true + /function-bind/1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true + /function-loop/2.0.1: resolution: {integrity: sha512-ktIR+O6i/4h+j/ZhZJNdzeI4i9lEPeEK6UPR2EVyTVBqOwcU3Za9xYKLH64ZR9HmcROyRrOkizNyjjtWJzDDkQ==} dev: true + /function.prototype.name/1.1.5: + resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.1 + functions-have-names: 1.2.3 + dev: true + /functional-red-black-tree/1.0.1: resolution: {integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=} dev: true + /functions-have-names/1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + /gensync/1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -1322,11 +1585,27 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} dev: true + /get-intrinsic/1.1.2: + resolution: {integrity: sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==} + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-symbols: 1.0.3 + dev: true + /get-package-type/0.1.0: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} dev: true + /get-symbol-description/1.0.0: + resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.2 + dev: true + /getpass/0.1.7: resolution: {integrity: sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=} dependencies: @@ -1337,7 +1616,14 @@ packages: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} dependencies: - is-glob: 4.0.1 + is-glob: 4.0.3 + dev: true + + /glob-parent/6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 dev: true /glob/7.1.7: @@ -1356,28 +1642,21 @@ packages: engines: {node: '>=4'} dev: true - /globals/12.4.0: - resolution: {integrity: sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.8.1 - dev: true - - /globals/13.8.0: - resolution: {integrity: sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==} + /globals/13.15.0: + resolution: {integrity: sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==} engines: {node: '>=8'} dependencies: type-fest: 0.20.2 dev: true - /globby/11.0.3: - resolution: {integrity: sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==} + /globby/11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} dependencies: array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.2.5 - ignore: 5.1.8 + fast-glob: 3.2.11 + ignore: 5.2.0 merge2: 1.4.1 slash: 3.0.0 dev: true @@ -1400,6 +1679,10 @@ packages: har-schema: 2.0.0 dev: true + /has-bigints/1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + /has-flag/3.0.0: resolution: {integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=} engines: {node: '>=4'} @@ -1410,6 +1693,31 @@ packages: engines: {node: '>=8'} dev: true + /has-property-descriptors/1.0.0: + resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + dependencies: + get-intrinsic: 1.1.2 + dev: true + + /has-symbols/1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-tostringtag/1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /has/1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: true + /hasha/5.2.2: resolution: {integrity: sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==} engines: {node: '>=8'} @@ -1431,13 +1739,8 @@ packages: sshpk: 1.16.1 dev: true - /ignore/4.0.6: - resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} - engines: {node: '>= 4'} - dev: true - - /ignore/5.1.8: - resolution: {integrity: sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==} + /ignore/5.2.0: + resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==} engines: {node: '>= 4'} dev: true @@ -1467,7 +1770,7 @@ packages: dev: true /imurmurhash/0.1.4: - resolution: {integrity: sha1-khi5srkoojixPcT7a21XbyMUU+o=} + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} dev: true @@ -1487,6 +1790,21 @@ packages: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} dev: true + /internal-slot/1.0.3: + resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.1.2 + has: 1.0.3 + side-channel: 1.0.4 + dev: true + + /is-bigint/1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + /is-binary-path/2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -1494,6 +1812,32 @@ packages: binary-extensions: 2.2.0 dev: true + /is-boolean-object/1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-callable/1.2.4: + resolution: {integrity: sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module/2.9.0: + resolution: {integrity: sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==} + dependencies: + has: 1.0.3 + dev: true + + /is-date-object/1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + /is-extglob/2.1.1: resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=} engines: {node: '>=0.10.0'} @@ -1523,20 +1867,73 @@ packages: is-extglob: 2.1.1 dev: true + /is-glob/4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-negative-zero/2.0.2: + resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object/1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + /is-number/7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} dev: true + /is-regex/1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-shared-array-buffer/1.0.2: + resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + dependencies: + call-bind: 1.0.2 + dev: true + /is-stream/2.0.0: resolution: {integrity: sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==} engines: {node: '>=8'} dev: true + /is-string/1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-symbol/1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + /is-typedarray/1.0.0: resolution: {integrity: sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=} dev: true + /is-weakref/1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.2 + dev: true + /is-windows/1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} @@ -1634,6 +2031,13 @@ packages: esprima: 4.0.1 dev: true + /js-yaml/4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + /jsbn/0.1.1: resolution: {integrity: sha1-peZUwuWi3rXyAdls77yoDA7y9RM=} dev: true @@ -1648,22 +2052,25 @@ packages: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} dev: true - /json-schema-traverse/1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - dev: true - /json-schema/0.2.3: resolution: {integrity: sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=} dev: true /json-stable-stringify-without-jsonify/1.0.1: - resolution: {integrity: sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=} + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} dev: true /json-stringify-safe/5.0.1: resolution: {integrity: sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=} dev: true + /json5/1.0.1: + resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} + hasBin: true + dependencies: + minimist: 1.2.6 + dev: true + /json5/2.2.0: resolution: {integrity: sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==} engines: {node: '>=6'} @@ -1715,6 +2122,14 @@ packages: yapool: 1.0.0 dev: true + /locate-path/2.0.0: + resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} + engines: {node: '>=4'} + dependencies: + p-locate: 2.0.0 + path-exists: 3.0.0 + dev: true + /locate-path/5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -1722,24 +2137,12 @@ packages: p-locate: 4.1.0 dev: true - /lodash.clonedeep/4.5.0: - resolution: {integrity: sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=} - dev: true - - /lodash.flatten/4.4.0: - resolution: {integrity: sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=} - dev: true - /lodash.flattendeep/4.4.0: resolution: {integrity: sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=} dev: true - /lodash.truncate/4.4.2: - resolution: {integrity: sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=} - dev: true - - /lodash/4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + /lodash.merge/4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true /log-driver/1.2.7: @@ -1777,12 +2180,12 @@ packages: engines: {node: '>= 8'} dev: true - /micromatch/4.0.4: - resolution: {integrity: sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==} + /micromatch/4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} dependencies: braces: 3.0.2 - picomatch: 2.3.0 + picomatch: 2.3.1 dev: true /mime-db/1.48.0: @@ -1803,10 +2206,20 @@ packages: brace-expansion: 1.1.11 dev: true + /minimatch/3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + /minimist/1.2.5: resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==} dev: true + /minimist/1.2.6: + resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} + dev: true + /minipass/3.1.3: resolution: {integrity: sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==} engines: {node: '>=8'} @@ -1820,12 +2233,16 @@ packages: hasBin: true dev: true + /ms/2.0.0: + resolution: {integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=} + dev: true + /ms/2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} dev: true /natural-compare/1.4.0: - resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=} + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true /node-preload/0.2.1: @@ -1894,6 +2311,34 @@ packages: engines: {node: '>=0.10.0'} dev: true + /object-inspect/1.12.2: + resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} + dev: true + + /object-keys/1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign/4.1.2: + resolution: {integrity: sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /object.values/1.1.5: + resolution: {integrity: sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.1 + dev: true + /once/1.4.0: resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=} dependencies: @@ -1927,6 +2372,13 @@ packages: resolution: {integrity: sha1-Tod/vtqaLsgAD7wLyuOWRe6L+Nw=} dev: true + /p-limit/1.3.0: + resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} + engines: {node: '>=4'} + dependencies: + p-try: 1.0.0 + dev: true + /p-limit/2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -1934,6 +2386,13 @@ packages: p-try: 2.2.0 dev: true + /p-locate/2.0.0: + resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} + engines: {node: '>=4'} + dependencies: + p-limit: 1.3.0 + dev: true + /p-locate/4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -1948,6 +2407,11 @@ packages: aggregate-error: 3.1.0 dev: true + /p-try/1.0.0: + resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} + engines: {node: '>=4'} + dev: true + /p-try/2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} @@ -1970,6 +2434,11 @@ packages: callsites: 3.1.0 dev: true + /path-exists/3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + dev: true + /path-exists/4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -1985,6 +2454,10 @@ packages: engines: {node: '>=8'} dev: true + /path-parse/1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + /path-type/4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -1999,6 +2472,11 @@ packages: engines: {node: '>=8.6'} dev: true + /picomatch/2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + /pkg-dir/4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} @@ -2018,8 +2496,8 @@ packages: fast-diff: 1.2.0 dev: true - /prettier/2.2.1: - resolution: {integrity: sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==} + /prettier/2.6.2: + resolution: {integrity: sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==} engines: {node: '>=10.13.0'} hasBin: true dev: true @@ -2031,11 +2509,6 @@ packages: fromentries: 1.3.2 dev: true - /progress/2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} - dev: true - /prop-types/15.7.2: resolution: {integrity: sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==} dependencies: @@ -2086,8 +2559,17 @@ packages: picomatch: 2.3.0 dev: true - /regexpp/3.1.0: - resolution: {integrity: sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==} + /regexp.prototype.flags/1.4.3: + resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + functions-have-names: 1.2.3 + dev: true + + /regexpp/3.2.0: + resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} engines: {node: '>=8'} dev: true @@ -2130,11 +2612,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /require-from-string/2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} - dev: true - /require-main-filename/2.0.0: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} dev: true @@ -2154,6 +2631,15 @@ packages: engines: {node: '>=8'} dev: true + /resolve/1.22.1: + resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + hasBin: true + dependencies: + is-core-module: 2.9.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + /reusify/1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -2189,8 +2675,8 @@ packages: hasBin: true dev: true - /semver/7.3.5: - resolution: {integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==} + /semver/7.3.7: + resolution: {integrity: sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==} engines: {node: '>=10'} hasBin: true dependencies: @@ -2213,6 +2699,14 @@ packages: engines: {node: '>=8'} dev: true + /side-channel/1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.2 + object-inspect: 1.12.2 + dev: true + /signal-exit/3.0.3: resolution: {integrity: sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==} dev: true @@ -2222,15 +2716,6 @@ packages: engines: {node: '>=8'} dev: true - /slice-ansi/4.0.0: - resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - astral-regex: 2.0.0 - is-fullwidth-code-point: 3.0.0 - dev: true - /source-map-support/0.5.19: resolution: {integrity: sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==} dependencies: @@ -2313,6 +2798,22 @@ packages: strip-ansi: 6.0.0 dev: true + /string.prototype.trimend/1.0.5: + resolution: {integrity: sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.1 + dev: true + + /string.prototype.trimstart/1.0.5: + resolution: {integrity: sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.1 + dev: true + /strip-ansi/3.0.1: resolution: {integrity: sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=} engines: {node: '>=0.10.0'} @@ -2334,6 +2835,18 @@ packages: ansi-regex: 5.0.0 dev: true + /strip-ansi/6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-bom/3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + /strip-bom/4.0.0: resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} engines: {node: '>=8'} @@ -2358,17 +2871,9 @@ packages: has-flag: 4.0.0 dev: true - /table/6.5.1: - resolution: {integrity: sha512-xGDXWTBJxahkzPQCsn1S9ESHEenU7TbMD5Iv4FeopXv/XwJyWatFjfbor+6ipI10/MNPXBYUamYukOrbPZ9L/w==} - engines: {node: '>=10.0.0'} - dependencies: - ajv: 8.1.0 - lodash.clonedeep: 4.5.0 - lodash.flatten: 4.4.0 - lodash.truncate: 4.4.2 - slice-ansi: 4.0.0 - string-width: 4.2.2 - strip-ansi: 6.0.0 + /supports-preserve-symlinks-flag/1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} dev: true /tap-mocha-reporter/5.0.1: @@ -2471,7 +2976,7 @@ packages: dev: true /text-table/0.2.0: - resolution: {integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=} + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true /to-fast-properties/2.0.0: @@ -2527,6 +3032,15 @@ packages: yn: 3.1.1 dev: true + /tsconfig-paths/3.14.1: + resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==} + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.1 + minimist: 1.2.6 + strip-bom: 3.0.0 + dev: true + /tslib/1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} dev: true @@ -2580,6 +3094,15 @@ packages: hasBin: true dev: true + /unbox-primitive/1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.2 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + dev: true + /unicode-length/2.0.2: resolution: {integrity: sha512-Ph/j1VbS3/r77nhoY2WU0GWGjVYOHL3xpKp0y/Eq2e5r0mT/6b649vm7KFO6RdAdrZkYLdxphYVgvODxPB+Ebg==} dependencies: @@ -2612,6 +3135,16 @@ packages: extsprintf: 1.3.0 dev: true + /which-boxed-primitive/1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + /which-module/2.0.0: resolution: {integrity: sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=} dev: true diff --git a/common/src/config/config.test.ts b/common/src/config/config.test.ts index 1ff82fb82..3c254a815 100644 --- a/common/src/config/config.test.ts +++ b/common/src/config/config.test.ts @@ -1,6 +1,6 @@ -import t from "tap"; import { GetGameConfig, GetGamePTConfig } from "./config"; import { allSupportedGames } from "./static-config"; +import t from "tap"; t.test("#GetGameConfig", (t) => { t.plan(allSupportedGames.length); @@ -18,6 +18,7 @@ t.test("#GetGamePTConfig", (t) => { for (const playtype of gameConfig.validPlaytypes) { const conf = GetGamePTConfig(game, playtype); + t.equal( conf.idString, `${game}:${playtype}`, diff --git a/common/src/config/config.ts b/common/src/config/config.ts index 705b79f1e..e9ac7059c 100644 --- a/common/src/config/config.ts +++ b/common/src/config/config.ts @@ -1,17 +1,16 @@ -import { FormatInt, GPTTierlists } from ".."; +import { FormatInt } from ".."; import { BMSGenocideDans, BMSLNDans, BMSScratchDans, BMSStSlDans, CHUNITHMColours, - ClassInfo, DDRDans, - GameClassSets, GitadoraColours, IIDXDans, JubeatColours, PMSDans, + // PMSDans, PopnClasses, SDVXDans, @@ -19,8 +18,11 @@ import { WaccaColours, WaccaStageUps, } from "../game-classes"; -import { ESDJudgementFormat } from "../lib/esd"; -import { +import { FormatSieglindeBMS, FormatSieglindePMS } from "../utils/util"; +import type { GPTTierlists } from ".."; +import type { ClassInfo, GameClassSets } from "../game-classes"; +import type { ESDJudgementFormat } from "../lib/esd"; +import type { Playtypes, Game, Difficulties, @@ -33,13 +35,12 @@ import { JudgementLookup, GPTSupportedVersions, } from "../types"; -import { FormatSieglindeBMS, FormatSieglindePMS } from "../utils/util"; export interface GameConfig { internalName: string; name: string; defaultPlaytype: Playtypes[G]; - validPlaytypes: Playtypes[G][]; + validPlaytypes: Array; } interface BaseGamePTConfig { @@ -51,9 +52,9 @@ interface BaseGamePTConfig { defaultSessionRatingAlg: SessionCalculatedDataLookup[I]; defaultProfileRatingAlg: UGSRatingsLookup[I]; - scoreRatingAlgs: ScoreCalculatedDataLookup[I][]; - sessionRatingAlgs: SessionCalculatedDataLookup[I][]; - profileRatingAlgs: UGSRatingsLookup[I][]; + scoreRatingAlgs: Array; + sessionRatingAlgs: Array; + profileRatingAlgs: Array; scoreRatingAlgDescriptions: Record; sessionRatingAlgDescriptions: Record; @@ -65,35 +66,35 @@ interface BaseGamePTConfig { >; profileRatingAlgFormatters: Partial string>>; - difficulties: Difficulties[I][]; + difficulties: Array; shortDifficulties: Partial>; defaultDifficulty: Difficulties[I]; difficultyColours: Record; - grades: Grades[I][]; + grades: Array; gradeColours: Record; clearGrade: Grades[I]; - gradeBoundaries: number[] | null; + gradeBoundaries: Array | null; - lamps: Lamps[I][]; + lamps: Array; lampColours: Record; clearLamp: Lamps[I]; - classHumanisedFormat: Record; + classHumanisedFormat: Record>; - judgements: JudgementLookup[I][]; + judgements: Array; scoreBucket: "grade" | "lamp"; - supportedVersions: GPTSupportedVersions[I][]; + supportedVersions: Array; - tierlists: GPTTierlists[I][]; + tierlists: Array; tierlistDescriptions: Record; } interface GamePTConfigWithESD extends BaseGamePTConfig { supportsESD: true; - judgementWindows: ESDJudgementFormat[]; + judgementWindows: Array; } interface GamePTConfigWithoutESD extends BaseGamePTConfig { @@ -340,6 +341,7 @@ const GAME_PT_CONFIGS: GamePTConfigs = { MAX: COLOUR_SET.white, }, clearGrade: "A", + // IIDX has some unhinged grade boundaries... // You might think these two lines are identical, but they are not. The order of operations affects // floating point math at this point. @@ -537,6 +539,7 @@ const GAME_PT_CONFIGS: GamePTConfigs = { MAX: COLOUR_SET.white, }, clearGrade: "A", + // see iidx:SP for an explaination of why this is wrote like this. gradeBoundaries: [ 0, @@ -1099,6 +1102,7 @@ const GAME_PT_CONFIGS: GamePTConfigs = { MAX: COLOUR_SET.white, }, clearGrade: "A", + // see iidx:SP for an explaination of why this is wrote like this. gradeBoundaries: [ 0, @@ -1210,6 +1214,7 @@ const GAME_PT_CONFIGS: GamePTConfigs = { MAX: COLOUR_SET.white, }, clearGrade: "A", + // see iidx:SP for an explaination of why this is wrote like this. gradeBoundaries: [ 0, @@ -1277,8 +1282,7 @@ const GAME_PT_CONFIGS: GamePTConfigs = { profileRatingAlgs: ["MFCP", "ktRating"], scoreRatingAlgDescriptions: { - MFCP: - "Marvelous Full Combo Points. An algorithm used in LIFE4 that rewards players for getting MFCs.", + MFCP: "Marvelous Full Combo Points. An algorithm used in LIFE4 that rewards players for getting MFCs.", ktRating: "TODO REMOVE ME", }, profileRatingAlgDescriptions: { @@ -1409,8 +1413,7 @@ const GAME_PT_CONFIGS: GamePTConfigs = { profileRatingAlgs: ["MFCP", "ktRating"], scoreRatingAlgDescriptions: { - MFCP: - "Marvelous Full Combo Points. An algorithm used in LIFE4 that rewards players for getting MFCs.", + MFCP: "Marvelous Full Combo Points. An algorithm used in LIFE4 that rewards players for getting MFCs.", ktRating: "TODO REMOVE ME", }, profileRatingAlgDescriptions: { @@ -1589,6 +1592,7 @@ const GAME_PT_CONFIGS: GamePTConfigs = { "SSS+": COLOUR_SET.white, }, clearGrade: "A", + // @hack Maimai's top grade depends on the chart's maximum percent // we just set it at percentMax, but it's not technically correct gradeBoundaries: [0, 10, 20, 40, 60, 80, 90, 94, 97, 98, 99, 99.5, 100, Infinity], @@ -1822,8 +1826,7 @@ const GAME_PT_CONFIGS: GamePTConfigs = { }, profileRatingAlgDescriptions: { naiveRate: "A naive rating algorithm that just averages your 50 best scores.", - rate: - "Rating as it's implemented in game, taking 15 scores from the latest version and 35 from all old versions.", + rate: "Rating as it's implemented in game, taking 15 scores from the latest version and 35 from all old versions.", }, sessionRatingAlgDescriptions: { rate: "The average of your best 10 ratings this session.", @@ -1865,6 +1868,7 @@ const GAME_PT_CONFIGS: GamePTConfigs = { MASTER: COLOUR_SET.white, }, clearGrade: "S", + // i'm pretty sure the first grade is below the limit of reliable FPA accuracy gradeBoundaries: [0, 0.0001, 3.0001, 70, 80, 85, 90, 93, 95, 97, 98, 99, 100], @@ -1948,6 +1952,7 @@ const GAME_PT_CONFIGS: GamePTConfigs = { S: COLOUR_SET.teal, }, clearGrade: "A", + // TECHNICALLY THIS IS NOT CORRECT // A Fail is capped at A rank (82%), no matter what! gradeBoundaries: [0, 50, 62, 72, 82, 90, 95, 98], @@ -2117,6 +2122,7 @@ const GAME_PT_CONFIGS: GamePTConfigs = { MAX: COLOUR_SET.white, }, clearGrade: "A", + // see iidx:SP for an explaination of why this is wrote like this. gradeBoundaries: [ 0, @@ -2224,6 +2230,7 @@ const GAME_PT_CONFIGS: GamePTConfigs = { MAX: COLOUR_SET.white, }, clearGrade: "A", + // see iidx:SP for an explaination of why this is wrote like this. gradeBoundaries: [ 0, @@ -2396,5 +2403,6 @@ export function GetGamePTConfig( playtype: Playtypes[Game] ): GamePTConfig { const idString = `${game}:${playtype}` as IDStrings; - return (GAME_PT_CONFIGS[idString] as unknown) as GamePTConfig; + + return GAME_PT_CONFIGS[idString] as unknown as GamePTConfig; } diff --git a/common/src/config/static-config.ts b/common/src/config/static-config.ts index 4545f4d12..de54a4db6 100644 --- a/common/src/config/static-config.ts +++ b/common/src/config/static-config.ts @@ -1,4 +1,4 @@ -import { +import type { FileUploadImportTypes, IRImportTypes, APIImportTypes, @@ -8,7 +8,7 @@ import { GPTSupportedVersions, } from ".."; -export const fileImportTypes: FileUploadImportTypes[] = [ +export const fileImportTypes: Array = [ "file/eamusement-iidx-csv", "file/eamusement-sdvx-csv", "file/batch-manual", @@ -17,7 +17,7 @@ export const fileImportTypes: FileUploadImportTypes[] = [ "file/pli-iidx-csv", ]; -export const irImportTypes: IRImportTypes[] = [ +export const irImportTypes: Array = [ "ir/direct-manual", "ir/barbatos", "ir/fervidex", @@ -27,7 +27,7 @@ export const irImportTypes: IRImportTypes[] = [ "ir/kshook-sv6c", ]; -export const apiImportTypes: APIImportTypes[] = [ +export const apiImportTypes: Array = [ "api/arc-iidx", "api/arc-sdvx", "api/eag-iidx", @@ -37,13 +37,13 @@ export const apiImportTypes: APIImportTypes[] = [ "api/min-sdvx", ]; -export const allImportTypes: ImportTypes[] = [ +export const allImportTypes: Array = [ ...fileImportTypes, ...irImportTypes, ...apiImportTypes, ]; -export const allIDStrings: IDStrings[] = [ +export const allIDStrings: Array = [ "iidx:SP", "bms:14K", "bms:7K", @@ -65,7 +65,7 @@ export const allIDStrings: IDStrings[] = [ "itg:Stamina", ]; -export const allSupportedGames: Game[] = [ +export const allSupportedGames: Array = [ "iidx", "museca", "maimai", diff --git a/common/src/constants/game.ts b/common/src/constants/game.ts index 5839c7497..9a058f42b 100644 --- a/common/src/constants/game.ts +++ b/common/src/constants/game.ts @@ -1,112 +1,112 @@ export enum IIDX_LAMPS { - NO_PLAY, - FAILED, - ASSIST_CLEAR, - EASY_CLEAR, - CLEAR, - HARD_CLEAR, - EX_HARD_CLEAR, - FULL_COMBO, + NO_PLAY = 0, + FAILED = 1, + ASSIST_CLEAR = 2, + EASY_CLEAR = 3, + CLEAR = 4, + HARD_CLEAR = 5, + EX_HARD_CLEAR = 6, + FULL_COMBO = 7, } export enum CHUNITHM_LAMPS { - FAILED, - CLEAR, - FULL_COMBO, - ALL_JUSTICE, - ALL_JUSTICE_CRITICAL, + FAILED = 0, + CLEAR = 1, + FULL_COMBO = 2, + ALL_JUSTICE = 3, + ALL_JUSTICE_CRITICAL = 4, } export enum SDVX_LAMPS { - FAILED, - CLEAR, - EXCESSIVE_CLEAR, - ULTIMATE_CHAIN, - PERFECT_ULTIMATE_CHAIN, + FAILED = 0, + CLEAR = 1, + EXCESSIVE_CLEAR = 2, + ULTIMATE_CHAIN = 3, + PERFECT_ULTIMATE_CHAIN = 4, } export enum MUSECA_LAMPS { - FAILED, - CLEAR, - CONNECT_ALL, - PERFECT_CONNECT_ALL, + FAILED = 0, + CLEAR = 1, + CONNECT_ALL = 2, + PERFECT_CONNECT_ALL = 3, } export enum DDR_LAMPS { - FAILED, - CLEAR, - LIFE4, - FULL_COMBO, - GREAT_FULL_COMBO, - PERFECT_FULL_COMBO, - MARVELOUS_FULL_COMBO, + FAILED = 0, + CLEAR = 1, + LIFE4 = 2, + FULL_COMBO = 3, + GREAT_FULL_COMBO = 4, + PERFECT_FULL_COMBO = 5, + MARVELOUS_FULL_COMBO = 6, } export enum MAIMAI_LAMPS { - FAILED, - CLEAR, - FULL_COMBO, - ALL_PERFECT, - ALL_PERFECT_PLUS, + FAILED = 0, + CLEAR = 1, + FULL_COMBO = 2, + ALL_PERFECT = 3, + ALL_PERFECT_PLUS = 4, } export enum GITADORA_LAMPS { - FAILED, - CLEAR, - FULL_COMBO, - EXCELLENT, + FAILED = 0, + CLEAR = 1, + FULL_COMBO = 2, + EXCELLENT = 3, } export enum IIDX_GRADES { - F, - E, - D, - C, - B, - A, - AA, - AAA, - MAX_MINUS, - MAX, + F = 0, + E = 1, + D = 2, + C = 3, + B = 4, + A = 5, + AA = 6, + AAA = 7, + MAX_MINUS = 8, + MAX = 9, } export enum CHUNITHM_GRADES { - D, - C, - B, - BB, - BBB, - A, - AA, - AAA, - S, - SS, - SSS, + D = 0, + C = 1, + B = 2, + BB = 3, + BBB = 4, + A = 5, + AA = 6, + AAA = 7, + S = 8, + SS = 9, + SSS = 10, } export enum SDVX_GRADES { - D, - C, - B, - A, - A_PLUS, - AA, - AA_PLUS, - AAA, - AAA_PLUS, - S, + D = 0, + C = 1, + B = 2, + A = 3, + A_PLUS = 4, + AA = 5, + AA_PLUS = 6, + AAA = 7, + AAA_PLUS = 8, + S = 9, } export enum MUSECA_GRADES { - 没, - 拙, - 凡, - 佳, - 良, - 優, - 秀, - 傑, - 傑G, + 没 = 0, + 拙 = 1, + 凡 = 2, + 佳 = 3, + 良 = 4, + 優 = 5, + 秀 = 6, + 傑 = 7, + 傑G = 8, } /** @@ -116,57 +116,57 @@ export enum MUSECA_GRADES { * to 975K. */ export enum MUSECA_GRADES_ASCII { - ZERO, - K600, - K700, - K800, - K850, - K900, - K950, - K975, - K1000, + ZERO = 0, + K600 = 1, + K700 = 2, + K800 = 3, + K850 = 4, + K900 = 5, + K950 = 6, + K975 = 7, + K1000 = 8, } export enum DDR_GRADES { - D, - D_PLUS, - C_MINUS, - C, - C_PLUS, - B_MINUS, - B, - B_PLUS, - A_MINUS, - A, - A_PLUS, - AA_MINUS, - AA, - AA_PLUS, - AAA, + D = 0, + D_PLUS = 1, + C_MINUS = 2, + C = 3, + C_PLUS = 4, + B_MINUS = 5, + B = 6, + B_PLUS = 7, + A_MINUS = 8, + A = 9, + A_PLUS = 10, + AA_MINUS = 11, + AA = 12, + AA_PLUS = 13, + AAA = 14, } export enum MAIMAI_GRADES { - F, - E, - D, - C, - B, - A, - AA, - AAA, - S, - S_PLUS, - SS, - SS_PLUS, - SSS, - SSS_PLUS, + F = 0, + E = 1, + D = 2, + C = 3, + B = 4, + A = 5, + AA = 6, + AAA = 7, + S = 8, + S_PLUS = 9, + SS = 10, + SS_PLUS = 11, + SSS = 12, + SSS_PLUS = 13, } export enum GITADORA_GRADES { - C, - B, - A, - S, - SS, - MAX, + C = 0, + B = 1, + A = 2, + S = 3, + SS = 4, + MAX = 5, } diff --git a/common/src/constants/permissions.ts b/common/src/constants/permissions.ts index a03b021d5..600809257 100644 --- a/common/src/constants/permissions.ts +++ b/common/src/constants/permissions.ts @@ -1,4 +1,4 @@ -import { APIPermissions } from "../types"; +import type { APIPermissions } from "../types"; // Some parts of tachi-server and some parts of the schemas refer to this // in order to assert that permissions are correctly assigned. diff --git a/common/src/game-classes.ts b/common/src/game-classes.ts index 14e7b4205..e2b58c819 100644 --- a/common/src/game-classes.ts +++ b/common/src/game-classes.ts @@ -1,7 +1,7 @@ // Classes refer to things like dans. // Not the JS construct. -import { IDStrings, integer } from "./types"; +import type { IDStrings, integer } from "./types"; export interface ClassInfo { display: string; @@ -11,7 +11,7 @@ export interface ClassInfo { backgroundColor: string; color: string; }; - variant?: "primary" | "secondary" | "success" | "warning" | "danger" | "info"; + variant?: "danger" | "info" | "primary" | "secondary" | "success" | "warning"; } function mouseoverCSS(id: string, d: string, m: string, bg = "black", color = "white") { @@ -22,7 +22,7 @@ function mouseoverVariant( id: string, d: string, m: string, - variant: "primary" | "secondary" | "success" | "warning" | "danger" | "info" + variant: "danger" | "info" | "primary" | "secondary" | "success" | "warning" ) { return { id, display: d, mouseover: m, variant }; } @@ -30,7 +30,7 @@ function mouseoverVariant( function noMouseoverVariant( id: string, d: string, - variant: "primary" | "secondary" | "success" | "warning" | "danger" | "info" + variant: "danger" | "info" | "primary" | "secondary" | "success" | "warning" ) { return { id, display: d, variant }; } @@ -39,7 +39,7 @@ function noMouseoverCSS(id: string, d: string, bg = "#131313", color = "white") return { id, display: d, css: { backgroundColor: bg, color } }; } -export const IIDXDans: ClassInfo[] = [ +export const IIDXDans: Array = [ mouseoverCSS("KYU_7", "七級", "7th Kyu", "green"), mouseoverCSS("KYU_6", "六級", "6th Kyu", "green"), mouseoverCSS("KYU_5", "五級", "5th Kyu", "green"), @@ -61,7 +61,7 @@ export const IIDXDans: ClassInfo[] = [ mouseoverVariant("KAIDEN", "皆伝", "Kaiden", "warning"), ]; -export const GitadoraColours: ClassInfo[] = [ +export const GitadoraColours: Array = [ mouseoverCSS("WHITE", "白", "White", "white", "black"), mouseoverCSS("ORANGE", "橙", "Orange", "orange"), mouseoverCSS("ORANGE_GRD", "橙グラ", "Orange Gradient", "orange"), @@ -78,11 +78,12 @@ export const GitadoraColours: ClassInfo[] = [ mouseoverCSS("BRONZE", "銅", "Bronze", "bronze"), mouseoverCSS("SILVER", "銀", "Silver", "silver", "black"), mouseoverCSS("GOLD", "金", "Gold", "gold"), + // @todo #11 Come up with CSS for Gitadora's rainbow icon. mouseoverCSS("RAINBOW", "虹", "Rainbow", "todo"), ]; -export const BMSGenocideDans: ClassInfo[] = [ +export const BMSGenocideDans: Array = [ mouseoverCSS("NORMAL_1", "☆1", "Normal 1st Dan", "lightblue"), mouseoverCSS("NORMAL_2", "☆2", "Normal 2nd Dan", "lightblue"), mouseoverCSS("NORMAL_3", "☆3", "Normal 3rd Dan", "lightblue"), @@ -107,7 +108,7 @@ export const BMSGenocideDans: ClassInfo[] = [ mouseoverCSS("OVERJOY", "(^^)", "Overjoy", "purple"), ]; -export const BMSStSlDans: ClassInfo[] = [ +export const BMSStSlDans: Array = [ mouseoverCSS("SL0", "sl0", "Satellite 0"), mouseoverCSS("SL1", "sl1", "Satellite 1"), mouseoverCSS("SL2", "sl2", "Satellite 2"), @@ -135,7 +136,7 @@ export const BMSStSlDans: ClassInfo[] = [ mouseoverCSS("ST11", "st11", "Stella 11"), ]; -export const BMSLNDans: ClassInfo[] = [ +export const BMSLNDans: Array = [ mouseoverCSS("DAN_1", "◆1", "LN 1st Dan", "lightblue"), mouseoverCSS("DAN_2", "◆2", "LN 2nd Dan", "lightblue"), mouseoverCSS("DAN_3", "◆3", "LN 3rd Dan", "lightblue"), @@ -151,7 +152,7 @@ export const BMSLNDans: ClassInfo[] = [ mouseoverCSS("UDON", "◆うどん", "LN Udon", "gold"), ]; -export const BMSScratchDans: ClassInfo[] = [ +export const BMSScratchDans: Array = [ mouseoverCSS("KYU_7", "七級", "Scratch 7th Kyu", "green"), mouseoverCSS("KYU_6", "六級", "Scratch 6th Kyu", "green"), mouseoverCSS("KYU_5", "五級", "Scratch 5th Kyu", "green"), @@ -172,7 +173,7 @@ export const BMSScratchDans: ClassInfo[] = [ mouseoverVariant("KAIDEN", "皆伝", "Scratch Kaiden", "warning"), ]; -export const SDVXDans: ClassInfo[] = [ +export const SDVXDans: Array = [ mouseoverCSS("DAN_1", "LV.01", "1st Dan"), mouseoverCSS("DAN_2", "LV.02", "2nd Dan"), mouseoverCSS("DAN_3", "LV.03", "3rd Dan"), @@ -187,7 +188,7 @@ export const SDVXDans: ClassInfo[] = [ mouseoverCSS("INF", "LV.INF", "Inf. Dan", "purple", "gold"), ]; -export const SDVXVFClasses: ClassInfo[] = [ +export const SDVXVFClasses: Array = [ noMouseoverCSS("SIENNA_I", "Sienna I"), noMouseoverCSS("SIENNA_II", "Sienna II"), noMouseoverCSS("SIENNA_III", "Sienna III"), @@ -340,12 +341,12 @@ export interface GameClassSets { "maimai:Single": never; "jubeat:Single": "colour"; "museca:Single": never; - "bms:7K": "genocideDan" | "stslDan" | "lnDan" | "scratchDan"; + "bms:7K": "genocideDan" | "lnDan" | "scratchDan" | "stslDan"; "bms:14K": "genocideDan"; "chunithm:Single": "colour"; "gitadora:Gita": "colour"; "gitadora:Dora": "colour"; - "wacca:Single": "stageUp" | "colour"; + "wacca:Single": "colour" | "stageUp"; "pms:Controller": "dan"; "pms:Keyboard": "dan"; "itg:Stamina": never; diff --git a/common/src/index.test.ts b/common/src/index.test.ts index 562cdb4df..ed41de5f8 100644 --- a/common/src/index.test.ts +++ b/common/src/index.test.ts @@ -1,6 +1,5 @@ -import t from "tap"; - import * as tachiCommon from "./index"; +import t from "tap"; // we just check that we're exporting stuff properly t.test("Property Checks", (t) => { diff --git a/common/src/legacy/legacy-config.ts b/common/src/legacy/legacy-config.ts deleted file mode 100644 index a41c590a0..000000000 --- a/common/src/legacy/legacy-config.ts +++ /dev/null @@ -1,539 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-nocheck - -// disable all type checking, this is a legacy file and is only kept around -// as a reference - -import { Game, Playtypes, ChartDocument, ChartDocument } from "../types"; - -// human readable stuff for versions -const versionHuman: Record> = { - iidx: { - 0: "1st Style", - 1: "substream", - 2: "2nd Style", - 3: "3rd Style", - 4: "4th Style", - 5: "5th Style", - 6: "6th Style", - 7: "7th Style", - 8: "8th Style", - 9: "9th Style", - 10: "10th Style", - 11: "IIDX RED", - 12: "HAPPY SKY", - 13: "DISTORTED", - 14: "GOLD", - 15: "DJ TROOPERS", - 16: "EMPRESS", - 17: "SIRIUS", - 18: "Resort Anthem", - 19: "Lincle", - 20: "tricoro", - 21: "SPADA", - 22: "PENDUAL", - 23: "copula", - 24: "SINOBUZ", - 25: "CANNON BALLERS", - 26: "ROOTAGE", - 27: "HEROIC VERSE", - 28: "BISTROVER", - }, - museca: { - 1: "", - 1.5: "1+1/2", - }, - maimai: { - maimai: "", - maimaiplus: "PLUS", - green: "GReeN", - greenplus: "GReeN PLUS", - orange: "ORANGE", - orangeplus: "ORANGE PLUS", - pink: "PiNK", - pinkplus: "PiNK PLUS", - murasaki: "MURASAKi", - murasakiplus: "MURASAKi PLUS", - milk: "MiLK", - milkplus: "MiLK PLUS", - finale: "FiNALE", - }, - // jubeat: { - // jubeat: "", - // ripples: "ripples", - // knit: "knit", - // copious: "copious", - // saucer: "saucer", - // saucerfulfill: "saucer fulfill", - // prop: "prop", - // qubell: "Qubell", - // clan: "clan", - // festo: "festo", - // }, - // popn: { - // 1: "1", - // 2: "2", - // 3: "3", - // 4: "4", - // 5: "5", - // 6: "6", - // 7: "7", - // 8: "8", - // 9: "9", - // 10: "10", - // 11: "11", - // 12: "12 Iroha", - // 13: "13 CARNIVAL", - // 14: "14 FEVER!", - // 15: "15 ADVENTURE", - // 16: "16 PARTY♪", - // 17: "17 THE MOVIE", - // 18: "18 Sengoku", - // 19: "19 TUNE STREET", - // 20: "20 fantasia", - // park: "Sunny Park", - // lapis: "Lapistoria", - // eclale: "éclale", - // usaneko: "Usaneko", - // peace: "peace", - // }, - sdvx: { - booth: "BOOTH", - inf: "II -infinite infection-", - gw: "III GRAVITY WARS", - heaven: "IV HEAVENLY HAVEN", - vivid: "V VIVID WAVE", - }, - ddr: { - 1: "1st Mix", - 2: "2nd Mix", - 3: "3rd Mix", - 4: "4th Mix", - 5: "5th Mix", - max: "MAX", - max2: "MAX2", - extreme: "EXTREME", - snova: "SuperNOVA", - snova2: "SuperNOVA 2", - x: "X", - x2: "X2", - x3: "X3 vs. 2nd Mix", - 2013: "(2013)", - 2014: "(2014)", - a: "Ace", - a20: "A20", - }, - chunithm: { - chuni: "", - chuniplus: "PLUS", - air: "AIR", - airplus: "AIR PLUS", - star: "STAR", - starplus: "STAR PLUS", - amazon: "AMAZON", - amazonplus: "AMAZON PLUS", - crystal: "CRYSTAL", - crystalplus: "CRYSTAL PLUS", - }, - gitadora: { - xg: "XG", - xg2: "XG2", - xg3: "XG3", - gitadora: "", - overdrive: "OverDrive", - triboost: "Tri-Boost", - triboostplus: "Tri-Boost (Re:EVOLVE)", - matixx: "Matixx", - exchain: "EXCHAIN", - nextage: "NEX+AGE", - }, - bms: { - 0: "BMS", - }, - usc: { - 0: "USC", - }, -}; - -// release orders of the games. -const gameOrders = { - iidx: [ - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "10", - "11", - "12", - "13", - "14", - "15", - "16", - "17", - "18", - "19", - "20", - "21", - "22", - "23", - "24", - "25", - "26", - "27", - "28", - ], - museca: ["1", "1.5"], - maimai: [ - "maimai", - "maimaiplus", - "green", - "greenplus", - "orange", - "orangeplus", - "pink", - "pinkplus", - "murasaki", - "murasakiplus", - "milk", - "milkplus", - "finale", - ], - jubeat: [ - "jubeat", - "ripples", - "knit", - "copious", - "saucer", - "saucerfulfill", - "prop", - "qubell", - "clan", - "festo", - ], - popn: [ - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "10", - "11", - "12", - "13", - "14", - "15", - "16", - "17", - "18", - "19", - "20", - "park", - "lapis", - "eclale", - "usaneko", - "peace", - ], - sdvx: ["booth", "inf", "gw", "heaven", "vivid"], - ddr: [ - "1", - "2", - "3", - "4", - "5", - "max", - "max2", - "extreme", - "snova", - "snova2", - "x", - "x2", - "x3", - "2013", - "2014", - "a", - "a20", - ], - bms: ["0"], - chunithm: [ - "chuni", - "chuniplus", - "air", - "airplus", - "star", - "starplus", - "amazon", - "amazonplus", - "crystal", - "crystalplus", - ], - gitadora: [ - "gf1", - "gf2dm1", - "gf3dm2", - "gf4dm3", - "gf5dm4", - "gf6dm5", - "gf7dm6", - "gf8dm7", - "gf8dm7plus", - "gf9dm8", - "gf10dm9", - "gf11dm10", - "v", - "v2", - "v3", - "v4", - "v5", - "v6", - "v7", - "v8", - "xg", - "xg2", - "xg3", - "gitadora", - "overdrive", - "triboost", - "triboostplus", - "matixx", - "exchain", - "nextage", - ], - usc: ["0"], -}; - -function humaniseGame(game: T, pt?: Playtypes[T]): string { - if (!pt) { - return gameHuman[game]; - } - - if (validPlaytypes[game].length === 1) { - return gameHuman[game]; - } - - return `${gameHuman[game]} (${pt})`; -} - -const ratingParameters = { - iidx: { - failHarshnessMultiplier: 0.3, - pivotPercent: 0.7777, // Grade: AA - clearExpMultiplier: 1, - }, - bms: { - failHarshnessMultiplier: 0.5, - pivotPercent: 0.7777, // Grade: AA - clearExpMultiplier: 0.75, - }, - museca: { - failHarshnessMultiplier: 1, - pivotPercent: 0.8, // grade: not fail - clearExpMultiplier: 1, // no real reason - }, - popn: { - failHarshnessMultiplier: 1, - pivotPercent: 0.8, // grade: A - clearExpMultiplier: 0.4, // no real reason - }, - maimai: { - failHarshnessMultiplier: 1, - pivotPercent: 0.8, - clearExpMultiplier: 1, - }, - jubeat: { - failHarshnessMultiplier: 0.9, - pivotPercent: 0.7, // grade: A (clear) - clearExpMultiplier: 1, - }, - sdvx: { - failHarshnessMultiplier: 1, - pivotPercent: 0.92, - clearExpMultiplier: 1.45, // testing - }, - usc: { - failHarshnessMultiplier: 1, - pivotPercent: 0.92, - clearExpMultiplier: 1.45, // testing - }, - ddr: { - failHarshnessMultiplier: 0.9, - pivotPercent: 0.9, - clearExpMultiplier: 1, - }, - chunithm: { - failHarshnessMultiplier: 1, - pivotPercent: 0.975, - clearExpMultiplier: 1.1, - }, - gitadora: { - // GENERIC PARAMS. THIS IS **NOT** THE USED CALC. - failHarshnessMultiplier: 1, - pivotPercent: 0.8, - clearExpMultiplier: 1.1, - }, -}; - -function ChangeAlpha(string: string, alpha: string): string { - const spl = string.split(","); - spl[spl.length - 1] = `${alpha})`; - return spl.join(","); -} - -function DirectScoreGradeDelta( - game: Game, - score: number, - percent: number, - chart: ChartDocument, - delta: number -): SGDReturn | null { - const grade = GetGrade(game, percent); - - if (!grade) { - throw new Error(`Invalid grade created from ${game}, ${percent}`); - } - - const scoreObj: PartialScore = { - scoreData: { - score, - grade, - }, - }; - - return ScoreGradeDelta(game, scoreObj, chart, delta); -} - -interface SGDReturn { - grade: string; - delta: number; - formattedString: string; -} - -interface PartialScore { - scoreData: { - score: number; - grade: string; - }; -} - -function ScoreGradeDelta( - game: Game, - score: PartialScore, - chart: ChartDocument, - delta: number -): SGDReturn | null { - const nextGrade = grades[game][grades[game].indexOf(score.scoreData.grade) + delta]; - - if (nextGrade) { - const nextGradePercent = gradeBoundaries[game][grades[game].indexOf(nextGrade)]; - - const nGScore = CalculateScore(game, nextGradePercent, chart); - - if (nGScore) { - const delta = score.scoreData.score - nGScore; - let formattedString = `(${nextGrade})`; - - if (Number.isInteger(delta)) { - formattedString += delta >= 0 ? `+${delta}` : `${delta}`; - } else { - formattedString += delta >= 0 ? `+${delta.toFixed(2)}` : `${delta.toFixed(2)}`; - } - - return { - grade: nextGrade, - delta: delta, - formattedString: formattedString, - }; - } else { - return null; - } - } else { - return null; - } -} - -function AbsoluteScoreGradeDelta( - game: Game, - score: number, - percent: number, - absDelta: number -): SGDReturn | null { - const grade = grades[game][absDelta]; - if (grade) { - let chart = null; - if (game === "iidx" || game === "bms") { - const reversedNC = Math.floor((score / percent) * 100) / 2; - chart = { - data: { - notecount: reversedNC, - }, - } as unknown; // heheh - } - - const sc = CalculateScore(game, gradeBoundaries[game][absDelta], chart as ChartDocument); - if (sc) { - const delta = score - sc; - let formattedString = `(${grade})`; - formattedString += delta >= 0 ? `+${delta}` : `${delta}`; - return { - grade: grade, - delta: delta, - formattedString: formattedString, - }; - } else { - return null; - } - } else { - return null; - } -} - -function CalculateScore(game: Game, percent: number, chart: ChartDocument): number | null { - let score = percent; - - if (game === "iidx" || game === "bms") { - score = (chart as ChartDocument<"iidx:SP">).data.notecount * 2 * (percent / 100); - } else if (game === "ddr" || game === "museca" || game === "jubeat" || game === "chunithm") { - score = 1_000_000 * (percent / 100); - } else if (game === "popn") { - score = 100_000 * (percent / 100); - } else if (game === "sdvx" || game === "usc") { - score = 10_000_000 * (percent / 100); - } - - if (score) { - return score; - } - return null; -} - -function PercentToScore(percent: number, game: Game, chartData: ChartDocument): number { - let eScore = 0; - - if (game === "iidx" || game === "bms") { - eScore = percent * (chartData as ChartDocument<"iidx:SP">).data.notecount * 2; - } else if (game === "museca" || game === "jubeat") { - eScore = percent * 1000000; - } else if (game === "popn") { - eScore = percent * 100000; - } else if (game === "sdvx" || game === "usc") { - eScore = percent * 10000000; - } else if (game === "ddr") { - // todo - } else if (game === "chunithm") { - eScore = percent * 1000000; - } else if (game === "gitadora") { - eScore = percent; - } - - return eScore; -} diff --git a/common/src/lib/esd.test.ts b/common/src/lib/esd.test.ts index 5c3e29883..39c227028 100644 --- a/common/src/lib/esd.test.ts +++ b/common/src/lib/esd.test.ts @@ -1,13 +1,13 @@ -import t from "tap"; -import { GetGamePTConfig } from "../config/config"; import { CalculateESD, ESDCompare, PercentCompare } from "./esd"; +import { GetGamePTConfig } from "../config/config"; +import t from "tap"; function approx(t: Tap.Test, given: number, recieved: number, acc = 0.01) { if (Math.abs(given - recieved) < acc) { return t.pass(); - } else { - return t.fail(`Expected ${given} to be within ${acc} of ${recieved}.`); } + + return t.fail(`Expected ${given} to be within ${acc} of ${recieved}.`); } const gptConfig = GetGamePTConfig("iidx", "SP"); @@ -20,6 +20,7 @@ const judgementWindows = gptConfig.judgementWindows; t.test("#CalculateESD", (t) => { const jdg = judgementWindows; + approx(t, CalculateESD(jdg, 0.8), 17.58); approx(t, CalculateESD(jdg, 0), 200); t.throws(() => CalculateESD(jdg, 0, true)); @@ -37,6 +38,7 @@ t.test("#ESDCompare", (t) => { t.test("#PercentCompare", (t) => { const jdg = judgementWindows; + approx(t, PercentCompare(jdg, 0.99, 0.98), -5.53); approx(t, PercentCompare(jdg, 0.99, 0.98), PercentCompare(jdg, 0.99, 0.98, 1)); diff --git a/common/src/lib/esd.ts b/common/src/lib/esd.ts index 3db5476aa..70ce50fb9 100644 --- a/common/src/lib/esd.ts +++ b/common/src/lib/esd.ts @@ -13,7 +13,8 @@ function cdf(x: number, mean: number, variance: number) { function erf(x: number) { // save the sign of x const sign = x >= 0 ? 1 : -1; - x = Math.abs(x); + + const absX = Math.abs(x); // constants const a1 = 0.254829592; @@ -24,8 +25,9 @@ function erf(x: number) { const p = 0.3275911; // A&S formula 7.1.26 - const t = 1.0 / (1.0 + p * x); - const y = 1.0 - ((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t * Math.exp(-x * x); + const t = 1.0 / (1.0 + p * absX); + const y = 1.0 - ((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t * Math.exp(-absX * absX); + return sign * y; // erf(-x) = -erf(x); } @@ -46,21 +48,21 @@ const MEAN = 0; * @returns The percent this std. deviation would produce. */ function StdDeviationToPercent( - judgements: ESDJudgementFormat[], + judgements: Array, stddev: number, largestValue: number ) { let lastJudgeMSBorder = 0; let prbSum = 0; - for (let i = 0; i < judgements.length; i++) { - const judge = judgements[i]; + for (const judge of judgements) { const nVal = CDFBetween(lastJudgeMSBorder, judge.msBorder, MEAN, stddev ** 2) * judge.value; + lastJudgeMSBorder = judge.msBorder; - prbSum += nVal; + prbSum = prbSum + nVal; } - prbSum /= largestValue; + prbSum = prbSum / largestValue; return prbSum; } @@ -83,7 +85,7 @@ export interface ESDJudgementFormat { * @returns */ export function CalculateESD( - judgements: ESDJudgementFormat[], + judgements: Array, percent: number, errOnInaccuracy = false ): number { @@ -92,6 +94,7 @@ export function CalculateESD( "(ESD) Invalid percent. Percent must be between 0 and 1, and also a number." ); } + const largestValue = judgements.slice(0).sort((a, b) => b.value - a.value)[0].value; // massive optimisation possible here by using better initial estimates with precalc'd table of values. @@ -128,7 +131,7 @@ export function CalculateESD( } if (errOnInaccuracy) { - throw `(ESD-JS) Did not reach value within MAX_ITERATIONS (${MAX_ITERATIONS})`; + throw new Error(`(ESD-JS) Did not reach value within MAX_ITERATIONS (${MAX_ITERATIONS})`); } return estSD; @@ -148,6 +151,7 @@ export function ESDCompare(baseESD: number, compareESD: number, cdeg = 1): numbe let inv = false; let variance; let bound; + if (compareESD > baseESD) { inv = true; variance = compareESD ** 2; @@ -162,7 +166,7 @@ export function ESDCompare(baseESD: number, compareESD: number, cdeg = 1): numbe let besdc = BASE_CASE - esdc; if (inv) { - besdc *= -1; + besdc = besdc * -1; } return besdc * 100; @@ -172,12 +176,13 @@ export function ESDCompare(baseESD: number, compareESD: number, cdeg = 1): numbe * Converts two percents to ESD, then runs ESDCompare. */ export function PercentCompare( - judgements: ESDJudgementFormat[], + judgements: Array, baseP: number, compareP: number, cdeg = 1 ): number { const e1 = CalculateESD(judgements, baseP); const e2 = CalculateESD(judgements, compareP); + return ESDCompare(e1, e2, cdeg); } diff --git a/common/src/lib/schemas.ts b/common/src/lib/schemas.ts index cfc426761..9b4f2e94a 100644 --- a/common/src/lib/schemas.ts +++ b/common/src/lib/schemas.ts @@ -2,15 +2,18 @@ // their name in the database to the object they schemaify. // The schemas themselves are wrapped in functions that throw on error. -import p, { +import { allIDStrings, allImportTypes, allSupportedGames } from "../config/static-config"; +import { ALL_PERMISSIONS } from "../constants/permissions"; +import { GetGameConfig, GetGamePTConfig } from "../index"; +import { UserAuthLevels } from "../types"; +import p from "prudence"; +import type { GamePTConfig } from "../index"; +import type { Game, IDStrings, NotificationBody, Playtypes } from "../types"; +import type { PrudenceSchema, ValidationFunctionParentOptionsKeychain, ValidSchemaValue, } from "prudence"; -import { allIDStrings, allImportTypes, allSupportedGames } from "../config/static-config"; -import { ALL_PERMISSIONS } from "../constants/permissions"; -import { GamePTConfig, GetGameConfig, GetGamePTConfig } from "../index"; -import { Game, IDStrings, NotificationBody, Playtypes, UserAuthLevels } from "../types"; export const optNull = (v: ValidSchemaValue): ValidationFunctionParentOptionsKeychain => p.optional(p.nullable(v)); @@ -33,7 +36,7 @@ function prSchemaFnWrap(schema: PrudenceSchema) { }; } -const PR_GameStats = (game: Game, playtype: Playtypes[Game], gptConfig: GamePTConfig) => ({ +const PR_GAME_STATS = (game: Game, playtype: Playtypes[Game], gptConfig: GamePTConfig) => ({ userID: p.isPositiveNonZeroInteger, game: p.is(game), playtype: p.is(playtype), @@ -43,7 +46,7 @@ const PR_GameStats = (game: Game, playtype: Playtypes[Game], gptConfig: GamePTCo ), }); -const PR_GoalInfo = { +const PR_GOAL_INFO = { progress: "?number", progressHuman: "string", outOf: "number", @@ -98,7 +101,8 @@ const extractGPTIDString = (self: unknown) => { throw new Error(`Expected a string where self.idString is. Got ${s.idString}`); } - const [game, playtype] = s.idString.split(":"); + // if there's no ":" in the string, this returns only one element. + const [game, playtype] = s.idString.split(":") as [string, string | undefined]; if (!IsValidGame(game)) { throw new Error(`Expected valid game -- got ${game} from idString ${s.idString}.`); @@ -138,12 +142,12 @@ const extractGPT = (self: unknown) => { return { game: s.game, playtype: s.playtype }; }; -const PR_Random = p.isIn("NONRAN", "RANDOM", "R-RANDOM", "S-RANDOM", "MIRROR"); +const PR_RANDOM = p.isIn("NONRAN", "RANDOM", "R-RANDOM", "S-RANDOM", "MIRROR"); const GetScoreMeta = (game: Game, playtype: Playtypes[Game]): PrudenceSchema => { if (game === "iidx" && playtype === "SP") { return { - random: optNull(PR_Random), + random: optNull(PR_RANDOM), assist: optNull(p.isIn("NO ASSIST", "AUTO SCRATCH", "LEGACY NOTE", "FULL ASSIST")), range: optNull(p.isIn("NONE", "SUDDEN+", "HIDDEN+", "SUD+ HID+", "LIFT", "LIFT SUD+")), gauge: optNull(p.isIn("ASSISTED EASY", "EASY", "NORMAL", "HARD", "EX-HARD")), @@ -151,8 +155,8 @@ const GetScoreMeta = (game: Game, playtype: Playtypes[Game]): PrudenceSchema => } else if (game === "iidx" && playtype === "DP") { return { random: optNull({ - left: PR_Random, - right: PR_Random, + left: PR_RANDOM, + right: PR_RANDOM, }), assist: optNull(p.isIn("NO ASSIST", "AUTO SCRATCH", "LEGACY NOTE", "FULL ASSIST")), range: optNull(p.isIn("NONE", "SUDDEN+", "HIDDEN+", "SUD+ HID+", "LIFT", "LIFT SUD+")), @@ -167,15 +171,15 @@ const GetScoreMeta = (game: Game, playtype: Playtypes[Game]): PrudenceSchema => }; } else if (game === "bms" && playtype === "7K") { return { - random: optNull(PR_Random), + random: optNull(PR_RANDOM), inputDevice: optNull(p.isIn("KEYBOARD", "BM_CONTROLLER")), client: optNull(p.isIn("LR2", "lr2oraja")), }; } else if (game === "bms" && playtype === "14K") { return { random: optNull({ - left: PR_Random, - right: PR_Random, + left: PR_RANDOM, + right: PR_RANDOM, }), inputDevice: optNull(p.isIn("KEYBOARD", "BM_CONTROLLER")), client: optNull(p.isIn("LR2", "lr2oraja")), @@ -194,7 +198,7 @@ function IsValidGame(str: string): str is Game { } const getPlaytype = (game: Game, self: unknown): Playtypes[Game] => { - if (!self || typeof self !== "object") { + if (self === null || typeof self !== "object") { throw new Error("Expected an object."); } @@ -203,6 +207,7 @@ const getPlaytype = (game: Game, self: unknown): Playtypes[Game] => { const s = self as Record; const playtype = s.playtype as string; + if (!IsValidPlaytype(game, playtype)) { throw new Error(`Expected any of ${gameConfig.validPlaytypes.join(", ")}`); } @@ -213,7 +218,7 @@ const getPlaytype = (game: Game, self: unknown): Playtypes[Game] => { const games = allSupportedGames; const isValidPlaytype = (self: unknown, parent: Record) => { - if (!parent.game || typeof parent.game !== "string" || !IsValidGame(parent.game)) { + if (typeof parent.game !== "string" || !IsValidGame(parent.game)) { throw new Error(`Invalid Schema, need game to base IsValidPlaytype off of.`); } @@ -416,7 +421,7 @@ function GetChartDataForGPT(idString: IDStrings): PrudenceSchema { } } -const PR_SongDocument = (game: Game): PrudenceSchema => { +const PR_SONG_DOCUMENT = (game: Game): PrudenceSchema => { const data = GetSongDataForGame(game); return { @@ -429,7 +434,7 @@ const PR_SongDocument = (game: Game): PrudenceSchema => { }; }; -const PR_ChartDocument = (game: Game) => (self: unknown) => { +const PR_CHART_DOCUMENT = (game: Game) => (self: unknown) => { const playtype = getPlaytype(game, self); const gptConfig = GetGamePTConfig(game, playtype); @@ -459,14 +464,14 @@ const PR_ChartDocument = (game: Game) => (self: unknown) => { // Returns true on success, throws on failure. export type SchemaValidatorFunction = (self: unknown) => true; -type GameSchemas = Record<`${"songs" | "charts"}-${Game}`, SchemaValidatorFunction>; +type GameSchemas = Record<`${"charts" | "songs"}-${Game}`, SchemaValidatorFunction>; function CreateGameSchemas() { const obj: Partial = {}; for (const game of games) { - obj[`songs-${game}`] = prSchemaFnWrap(PR_SongDocument(game)); - obj[`charts-${game}`] = PR_ChartDocument(game); + obj[`songs-${game}`] = prSchemaFnWrap(PR_SONG_DOCUMENT(game)); + obj[`charts-${game}`] = PR_CHART_DOCUMENT(game); } // guaranteed to no longer be partial @@ -486,6 +491,7 @@ const GAME_SCHEMAS = CreateGameSchemas(); const PRE_SCHEMAS = { "bms-course-lookup": prSchemaFnWrap({ title: "string", + // Must be comprised of 4 md5 hashes, which are 32 chars long. md5sums: (self) => { if (typeof self !== "string") { @@ -496,7 +502,7 @@ const PRE_SCHEMAS = { return "Expected 32 * 4 characters (4 md5 hashes long)."; } - if (!self.match(/^[a-z0-9]*$/u)) { + if (!/^[a-z0-9]*$/u.exec(self)) { return "Expected all chars to be in the range of a-z0-9."; } @@ -516,9 +522,9 @@ const PRE_SCHEMAS = { type: p.isIn("songs", "charts", "static"), data: (self, parent) => { if (parent.type === "songs") { - return true; //temp. should be a song. + return true; // temp. should be a song. } else if (parent.type === "charts") { - return true; //temp. should be a chart. + return true; // temp. should be a chart. } return ( @@ -652,14 +658,12 @@ const PRE_SCHEMAS = { const gptConfig = GetGamePTConfig(game, playtype); - const hitMeta = Object.assign( - { - fast: optNull(p.isPositiveInteger), - slow: optNull(p.isPositiveInteger), - maxCombo: optNull(p.isPositiveInteger), - }, - GetHitMeta(game) - ); + const hitMeta = { + fast: optNull(p.isPositiveInteger), + slow: optNull(p.isPositiveInteger), + maxCombo: optNull(p.isPositiveInteger), + ...GetHitMeta(game), + }; const scoreMeta = GetScoreMeta(game, playtype); @@ -701,14 +705,12 @@ const PRE_SCHEMAS = { const gptConfig = GetGamePTConfig(game, playtype); - const hitMeta = Object.assign( - { - fast: optNull(p.isPositiveInteger), - slow: optNull(p.isPositiveInteger), - maxCombo: optNull(p.isPositiveInteger), - }, - GetHitMeta(game) - ); + const hitMeta = { + fast: optNull(p.isPositiveInteger), + slow: optNull(p.isPositiveInteger), + maxCombo: optNull(p.isPositiveInteger), + ...GetHitMeta(game), + }; return prSchemaFnWrap({ composedFrom: { @@ -803,6 +805,7 @@ const PRE_SCHEMAS = { importID: "string", scoreIDs: ["string"], game: p.isIn(games), + // @ts-expect-error We've asserted this is definitely a game. playtypes: [(self) => p.isIn(GetGameConfig(self.game).validPlaytypes)(self)], errors: [ @@ -830,8 +833,8 @@ const PRE_SCHEMAS = { goalInfo: [ { goalID: "string", - old: PR_GoalInfo, - new: PR_GoalInfo, + old: PR_GOAL_INFO, + new: PR_GOAL_INFO, }, ], milestoneInfo: [ @@ -857,7 +860,7 @@ const PRE_SCHEMAS = { const gptConfig = GetGamePTConfig(game, playtype); - return prSchemaFnWrap(PR_GameStats(game, playtype, gptConfig))(self); + return prSchemaFnWrap(PR_GAME_STATS(game, playtype, gptConfig))(self); }, "game-stats-snapshots": (self: unknown) => { const { game, playtype } = extractGPT(self); @@ -865,7 +868,7 @@ const PRE_SCHEMAS = { const gptConfig = GetGamePTConfig(game, playtype); return prSchemaFnWrap( - Object.assign(PR_GameStats(game, playtype, gptConfig), { + Object.assign(PR_GAME_STATS(game, playtype, gptConfig), { rankings: Object.fromEntries( gptConfig.profileRatingAlgs.map((e) => [ e, @@ -890,6 +893,7 @@ const PRE_SCHEMAS = { preferredScoreAlg: p.nullable(p.isIn(gptConfig.scoreRatingAlgs)), preferredSessionAlg: p.nullable(p.isIn(gptConfig.sessionRatingAlgs)), preferredProfileAlg: p.nullable(p.isIn(gptConfig.profileRatingAlgs)), + // ouch stats: p.and( [ @@ -991,7 +995,7 @@ const PRE_SCHEMAS = { // Typescript moment... const s = self as Record; - for (const key in ALL_PERMISSIONS) { + for (const key of Object.keys(ALL_PERMISSIONS)) { if (s[key] !== undefined && typeof s[key] !== "boolean") { return `Invalid permission value of ${s[key]} at ${key}.`; } @@ -1016,8 +1020,8 @@ const PRE_SCHEMAS = { return prSchemaFnWrap({ idString: p.isIn(allIDStrings), - chartDoc: PR_ChartDocument(game), - songDoc: PR_SongDocument(game), + chartDoc: PR_CHART_DOCUMENT(game), + songDoc: PR_SONG_DOCUMENT(game), userIDs: [p.isPositiveNonZeroInteger], })(self); }, @@ -1050,16 +1054,9 @@ const PRE_SCHEMAS = { ["import", "importParse", "session", "pb"].map((k) => [k, p.isPositive]) ), abs: Object.fromEntries( - [ - "parse", - "import", - "importParse", - "session", - "pb", - "ugs", - "goal", - "milestone", - ].map((k) => [k, p.isPositive]) + ["parse", "import", "importParse", "session", "pb", "ugs", "goal", "milestone"].map( + (k) => [k, p.isPositive] + ) ), }), "arc-saved-profiles": prSchemaFnWrap({ @@ -1073,14 +1070,14 @@ const PRE_SCHEMAS = { createdAt: p.isPositive, consumed: "boolean", consumedBy: (self, parent) => { - if (parent.consumed) { + if (parent.consumed === true) { return self === null; } return p.isPositiveInteger(self); }, consumedAt: (self, parent) => { - if (parent.consumed) { + if (parent.consumed === true) { return self === null; } @@ -1100,16 +1097,20 @@ const PRE_SCHEMAS = { let subSchema = {}; - if (type === "RIVALED_BY") { - subSchema = { - userID: p.isPositiveNonZeroInteger, - game: p.isIn(games), - playtype: isValidPlaytype, - }; - } else if (type === "MILESTONE_CHANGED") { - subSchema = { - milestoneID: "string", - }; + switch (type) { + case "RIVALED_BY": { + subSchema = { + userID: p.isPositiveNonZeroInteger, + game: p.isIn(games), + playtype: isValidPlaytype, + }; + break; + } + + case "MILESTONE_CHANGED": + subSchema = { + milestoneID: "string", + }; } const err = p(self, subSchema); diff --git a/common/src/types.ts b/common/src/types.ts index b71a103d1..1bf569a09 100644 --- a/common/src/types.ts +++ b/common/src/types.ts @@ -1,12 +1,12 @@ // Monk type-stub to avoid pulling the whole dep in +import type { AllClassSets, GameClasses, GameClassSets } from "./game-classes"; +import type { FilterQuery } from "mongodb"; + export interface IObjectID { readonly toHexString: () => string; readonly toString: () => string; } -import { FilterQuery } from "mongodb"; -import { AllClassSets, GameClasses, GameClassSets } from "./game-classes"; - export interface CounterDocument { counterName: string; value: integer; @@ -21,26 +21,26 @@ export type Playtype = Playtypes[Game]; * like the ScoreDocument (Especially the ScoreDocument) *very* hard! */ export type IDStrings = - | "iidx:SP" - | "iidx:DP" - | "popn:9B" - | "sdvx:Single" - | "usc:Keyboard" - | "usc:Controller" - | "ddr:SP" - | "ddr:DP" - | "maimai:Single" - | "museca:Single" - | "jubeat:Single" | "bms:7K" | "bms:14K" | "chunithm:Single" - | "gitadora:Gita" + | "ddr:DP" + | "ddr:SP" | "gitadora:Dora" - | "wacca:Single" - | "pms:Keyboard" + | "gitadora:Gita" + | "iidx:DP" + | "iidx:SP" + | "itg:Stamina" + | "jubeat:Single" + | "maimai:Single" + | "museca:Single" | "pms:Controller" - | "itg:Stamina"; + | "pms:Keyboard" + | "popn:9B" + | "sdvx:Single" + | "usc:Controller" + | "usc:Keyboard" + | "wacca:Single"; export interface IDStringToPlaytype { "iidx:SP": "SP"; @@ -89,19 +89,19 @@ export interface IDStringToGame { } export interface GameToIDStrings { - iidx: "iidx:SP" | "iidx:DP"; + iidx: "iidx:DP" | "iidx:SP"; sdvx: "sdvx:Single"; - usc: "usc:Keyboard" | "usc:Controller"; - ddr: "ddr:SP" | "ddr:DP"; + usc: "usc:Controller" | "usc:Keyboard"; + ddr: "ddr:DP" | "ddr:SP"; maimai: "maimai:Single"; jubeat: "jubeat:Single"; museca: "museca:Single"; bms: "bms:7K" | "bms:14K"; chunithm: "chunithm:Single"; - gitadora: "gitadora:Gita" | "gitadora:Dora"; + gitadora: "gitadora:Dora" | "gitadora:Gita"; popn: "popn:9B"; wacca: "wacca:Single"; - pms: "pms:Keyboard" | "pms:Controller"; + pms: "pms:Controller" | "pms:Keyboard"; itg: "itg:Stamina"; } @@ -124,20 +124,20 @@ export interface MongoDBDocument { * All supported games by Tachi. */ export type Game = - | "iidx" - | "museca" - | "maimai" - | "jubeat" - | "popn" - | "sdvx" - | "ddr" | "bms" | "chunithm" + | "ddr" | "gitadora" - | "usc" - | "wacca" + | "iidx" + | "itg" + | "jubeat" + | "maimai" + | "museca" | "pms" - | "itg"; + | "popn" + | "sdvx" + | "usc" + | "wacca"; /** * This is the generic response from the Kamaitachi API in event of a failure. @@ -154,6 +154,7 @@ export interface UnsuccessfulAPIResponse { export interface SuccessfulAPIResponse { success: true; description: string; + // This isn't ideal, but we need to restrict // this to only objects - Record // mandates indexability of the type, which makes @@ -167,174 +168,174 @@ export interface ChartFolderLookupDocument extends MongoDBDocument { } export interface Playtypes { - iidx: "SP" | "DP"; + iidx: "DP" | "SP"; popn: "9B"; sdvx: "Single"; - usc: "Keyboard" | "Controller"; - ddr: "SP" | "DP"; + usc: "Controller" | "Keyboard"; + ddr: "DP" | "SP"; maimai: "Single"; jubeat: "Single"; museca: "Single"; chunithm: "Single"; bms: "7K" | "14K"; - gitadora: "Gita" | "Dora"; + gitadora: "Dora" | "Gita"; wacca: "Single"; - pms: "Keyboard" | "Controller"; + pms: "Controller" | "Keyboard"; itg: "Stamina"; } -type IIDXGrades = "F" | "E" | "D" | "C" | "B" | "A" | "AA" | "AAA" | "MAX-" | "MAX"; -type SDVXGrades = "D" | "C" | "B" | "A" | "A+" | "AA" | "AA+" | "AAA" | "AAA+" | "S" | "PUC"; +type IIDXGrades = "A" | "AA" | "AAA" | "B" | "C" | "D" | "E" | "F" | "MAX-" | "MAX"; +type SDVXGrades = "A" | "A+" | "AA" | "AA+" | "AAA" | "AAA+" | "B" | "C" | "D" | "PUC" | "S"; type DDRGrades = - | "D" - | "D+" - | "C-" - | "C" - | "C+" - | "B-" - | "B" - | "B+" | "A-" | "A" | "A+" | "AA-" | "AA" | "AA+" - | "AAA"; + | "AAA" + | "B-" + | "B" + | "B+" + | "C-" + | "C" + | "C+" + | "D" + | "D+"; -type GitadoraGrades = "C" | "B" | "A" | "S" | "SS" | "MAX"; +type GitadoraGrades = "A" | "B" | "C" | "MAX" | "S" | "SS"; export interface Grades { "iidx:SP": IIDXGrades; "iidx:DP": IIDXGrades; - "popn:9B": "E" | "D" | "C" | "B" | "A" | "AA" | "AAA" | "S"; + "popn:9B": "A" | "AA" | "AAA" | "B" | "C" | "D" | "E" | "S"; "sdvx:Single": SDVXGrades; "usc:Keyboard": SDVXGrades; "usc:Controller": SDVXGrades; "ddr:SP": DDRGrades; "ddr:DP": DDRGrades; "maimai:Single": - | "F" - | "E" - | "D" - | "C" - | "B" | "A" | "AA" | "AAA" + | "B" + | "C" + | "D" + | "E" + | "F" | "S" | "S+" | "SS" | "SS+" | "SSS" | "SSS+"; - "jubeat:Single": "E" | "D" | "C" | "B" | "A" | "S" | "SS" | "SSS" | "EXC"; - "museca:Single": "没" | "拙" | "凡" | "佳" | "良" | "優" | "秀" | "傑" | "傑G"; + "jubeat:Single": "A" | "B" | "C" | "D" | "E" | "EXC" | "S" | "SS" | "SSS"; + "museca:Single": "佳" | "傑" | "傑G" | "優" | "凡" | "拙" | "没" | "秀" | "良"; "bms:7K": IIDXGrades; "bms:14K": IIDXGrades; - "chunithm:Single": "D" | "C" | "B" | "BB" | "BBB" | "A" | "AA" | "AAA" | "S" | "SS" | "SSS"; + "chunithm:Single": "A" | "AA" | "AAA" | "B" | "BB" | "BBB" | "C" | "D" | "S" | "SS" | "SSS"; "gitadora:Gita": GitadoraGrades; "gitadora:Dora": GitadoraGrades; "wacca:Single": - | "D" - | "C" - | "B" | "A" | "AA" | "AAA" + | "B" + | "C" + | "D" + | "MASTER" | "S" | "S+" | "SS" | "SS+" | "SSS" - | "SSS+" - | "MASTER"; + | "SSS+"; "pms:Controller": IIDXGrades; "pms:Keyboard": IIDXGrades; - "itg:Stamina": "D" | "C" | "B" | "A" | "S-" | "S" | "S+" | "★" | "★★" | "★★★" | "★★★★"; + "itg:Stamina": "★" | "★★" | "★★★" | "★★★★" | "A" | "B" | "C" | "D" | "S-" | "S" | "S+"; } type IIDXLamps = - | "NO PLAY" - | "FAILED" | "ASSIST CLEAR" - | "EASY CLEAR" | "CLEAR" - | "HARD CLEAR" + | "EASY CLEAR" | "EX HARD CLEAR" - | "FULL COMBO"; + | "FAILED" + | "FULL COMBO" + | "HARD CLEAR" + | "NO PLAY"; -type GitadoraLamps = "FAILED" | "CLEAR" | "FULL COMBO" | "EXCELLENT"; +type GitadoraLamps = "CLEAR" | "EXCELLENT" | "FAILED" | "FULL COMBO"; type SDVXLamps = - | "FAILED" | "CLEAR" | "EXCESSIVE CLEAR" - | "ULTIMATE CHAIN" - | "PERFECT ULTIMATE CHAIN"; + | "FAILED" + | "PERFECT ULTIMATE CHAIN" + | "ULTIMATE CHAIN"; type DDRLamps = - | "FAILED" | "CLEAR" - | "LIFE4" + | "FAILED" | "FULL COMBO" | "GREAT FULL COMBO" - | "PERFECT FULL COMBO" - | "MARVELOUS FULL COMBO"; + | "LIFE4" + | "MARVELOUS FULL COMBO" + | "PERFECT FULL COMBO"; export interface Lamps { "iidx:SP": IIDXLamps; "iidx:DP": IIDXLamps; - "popn:9B": "FAILED" | "EASY CLEAR" | "CLEAR" | "FULL COMBO" | "PERFECT"; + "popn:9B": "CLEAR" | "EASY CLEAR" | "FAILED" | "FULL COMBO" | "PERFECT"; "sdvx:Single": SDVXLamps; "usc:Keyboard": SDVXLamps; "usc:Controller": SDVXLamps; "ddr:SP": DDRLamps; "ddr:DP": DDRLamps; - "maimai:Single": "FAILED" | "CLEAR" | "FULL COMBO" | "ALL PERFECT" | "ALL PERFECT+"; - "jubeat:Single": "FAILED" | "CLEAR" | "FULL COMBO" | "EXCELLENT"; - "museca:Single": "FAILED" | "CLEAR" | "CONNECT ALL" | "PERFECT CONNECT ALL"; + "maimai:Single": "ALL PERFECT" | "ALL PERFECT+" | "CLEAR" | "FAILED" | "FULL COMBO"; + "jubeat:Single": "CLEAR" | "EXCELLENT" | "FAILED" | "FULL COMBO"; + "museca:Single": "CLEAR" | "CONNECT ALL" | "FAILED" | "PERFECT CONNECT ALL"; "bms:7K": IIDXLamps; "bms:14K": IIDXLamps; - "chunithm:Single": "FAILED" | "CLEAR" | "FULL COMBO" | "ALL JUSTICE" | "ALL JUSTICE CRITICAL"; + "chunithm:Single": "ALL JUSTICE CRITICAL" | "ALL JUSTICE" | "CLEAR" | "FAILED" | "FULL COMBO"; "gitadora:Gita": GitadoraLamps; "gitadora:Dora": GitadoraLamps; - "wacca:Single": "FAILED" | "CLEAR" | "MISSLESS" | "FULL COMBO" | "ALL MARVELOUS"; + "wacca:Single": "ALL MARVELOUS" | "CLEAR" | "FAILED" | "FULL COMBO" | "MISSLESS"; "pms:Controller": IIDXLamps; "pms:Keyboard": IIDXLamps; - "itg:Stamina": "FAILED" | "CLEAR" | "FULL COMBO" | "FULL EXCELLENT COMBO" | "QUAD"; + "itg:Stamina": "CLEAR" | "FAILED" | "FULL COMBO" | "FULL EXCELLENT COMBO" | "QUAD"; } -export type IIDX2DXTraSets = "Kichiku" | "Kiraku" | "All Scratch"; -export type IIDXSPDifficulties = "BEGINNER" | "NORMAL" | "HYPER" | "ANOTHER" | "LEGGENDARIA"; -export type IIDXDPDifficulties = "NORMAL" | "HYPER" | "ANOTHER" | "LEGGENDARIA"; +export type IIDX2DXTraSets = "All Scratch" | "Kichiku" | "Kiraku"; +export type IIDXSPDifficulties = "ANOTHER" | "BEGINNER" | "HYPER" | "LEGGENDARIA" | "NORMAL"; +export type IIDXDPDifficulties = "ANOTHER" | "HYPER" | "LEGGENDARIA" | "NORMAL"; export interface Difficulties { - "iidx:SP": `${`${IIDX2DXTraSets} ` | ""}${IIDXSPDifficulties}`; - "iidx:DP": `${`${IIDX2DXTraSets} ` | ""}${IIDXDPDifficulties}`; - "popn:9B": "Easy" | "Normal" | "Hyper" | "EX"; - "sdvx:Single": "NOV" | "ADV" | "EXH" | "MXM" | "INF" | "GRV" | "HVN" | "VVD"; - "usc:Controller": "NOV" | "ADV" | "EXH" | "INF"; - "usc:Keyboard": "NOV" | "ADV" | "EXH" | "INF"; - "ddr:SP": "BEGINNER" | "BASIC" | "DIFFICULT" | "EXPERT" | "CHALLENGE"; - "ddr:DP": "BASIC" | "DIFFICULT" | "EXPERT" | "CHALLENGE"; - "maimai:Single": "Easy" | "Basic" | "Advanced" | "Expert" | "Master" | "Re:Master"; - "jubeat:Single": "BSC" | "ADV" | "EXT" | "HARD BSC" | "HARD ADV" | "HARD EXT"; - "museca:Single": "Green" | "Yellow" | "Red"; + "iidx:SP": `${"" | `${IIDX2DXTraSets} `}${IIDXSPDifficulties}`; + "iidx:DP": `${"" | `${IIDX2DXTraSets} `}${IIDXDPDifficulties}`; + "popn:9B": "Easy" | "EX" | "Hyper" | "Normal"; + "sdvx:Single": "ADV" | "EXH" | "GRV" | "HVN" | "INF" | "MXM" | "NOV" | "VVD"; + "usc:Controller": "ADV" | "EXH" | "INF" | "NOV"; + "usc:Keyboard": "ADV" | "EXH" | "INF" | "NOV"; + "ddr:SP": "BASIC" | "BEGINNER" | "CHALLENGE" | "DIFFICULT" | "EXPERT"; + "ddr:DP": "BASIC" | "CHALLENGE" | "DIFFICULT" | "EXPERT"; + "maimai:Single": "Advanced" | "Basic" | "Easy" | "Expert" | "Master" | "Re:Master"; + "jubeat:Single": "ADV" | "BSC" | "EXT" | "HARD ADV" | "HARD BSC" | "HARD EXT"; + "museca:Single": "Green" | "Red" | "Yellow"; "bms:7K": "CHART"; "bms:14K": "CHART"; - "chunithm:Single": "BASIC" | "ADVANCED" | "EXPERT" | "MASTER"; + "chunithm:Single": "ADVANCED" | "BASIC" | "EXPERT" | "MASTER"; "gitadora:Gita": - | "BASIC" | "ADVANCED" - | "EXTREME" - | "MASTER" - | "BASS BASIC" + | "BASIC" | "BASS ADVANCED" + | "BASS BASIC" | "BASS EXTREME" - | "BASS MASTER"; - "gitadora:Dora": "BASIC" | "ADVANCED" | "EXTREME" | "MASTER"; - "wacca:Single": "NORMAL" | "HARD" | "EXPERT" | "INFERNO"; + | "BASS MASTER" + | "EXTREME" + | "MASTER"; + "gitadora:Dora": "ADVANCED" | "BASIC" | "EXTREME" | "MASTER"; + "wacca:Single": "EXPERT" | "HARD" | "INFERNO" | "NORMAL"; "pms:Controller": "CHART"; "pms:Keyboard": "CHART"; "itg:Stamina": string; @@ -355,11 +356,11 @@ export interface BaseGoalDocument extends MongoDBDocument { timeAdded: integer; name: string; goalID: string; - criteria: GoalSingleCriteria | GoalCountCriteria; + criteria: GoalCountCriteria | GoalSingleCriteria; } interface GoalCriteria { - key: "scoreData.percent" | "scoreData.lampIndex" | "scoreData.gradeIndex" | "scoreData.score"; + key: "scoreData.gradeIndex" | "scoreData.lampIndex" | "scoreData.percent" | "scoreData.score"; value: number; } @@ -393,7 +394,7 @@ export interface GoalDocumentSingle extends BaseGoalDocument { export interface GoalDocumentMulti extends BaseGoalDocument { charts: { type: "multi"; - data: string[]; + data: Array; }; } @@ -418,10 +419,10 @@ export interface GoalDocumentAny extends BaseGoalDocument { } export type GoalDocument = + | GoalDocumentAny | GoalDocumentFolder | GoalDocumentMulti - | GoalDocumentSingle - | GoalDocumentAny; + | GoalDocumentSingle; interface BaseInviteCodeDocument extends MongoDBDocument { createdBy: integer; @@ -437,7 +438,7 @@ export type InviteCodeDocument = BaseInviteCodeDocument & export interface SessionInfoReturn { sessionID: string; - type: "Created" | "Appended"; + type: "Appended" | "Created"; } interface SessionScorePBInfo { @@ -454,17 +455,17 @@ interface SessionScoreNewInfo { isNewScore: true; } -export type SessionScoreInfo = SessionScorePBInfo | SessionScoreNewInfo; +export type SessionScoreInfo = SessionScoreNewInfo | SessionScorePBInfo; export interface SessionCalculatedDataLookup { "iidx:SP": "BPI" | "ktLampRating"; "iidx:DP": "BPI" | "ktLampRating"; "popn:9B": "classPoints"; - "sdvx:Single": "VF6" | "ProfileVF6"; - "usc:Keyboard": "VF6" | "ProfileVF6"; - "usc:Controller": "VF6" | "ProfileVF6"; - "ddr:SP": "MFCP" | "ktRating"; - "ddr:DP": "MFCP" | "ktRating"; + "sdvx:Single": "ProfileVF6" | "VF6"; + "usc:Keyboard": "ProfileVF6" | "VF6"; + "usc:Controller": "ProfileVF6" | "VF6"; + "ddr:SP": "ktRating" | "MFCP"; + "ddr:DP": "ktRating" | "MFCP"; "maimai:Single": "ktRating"; "jubeat:Single": "jubility"; "museca:Single": "ktRating"; @@ -476,17 +477,18 @@ export interface SessionCalculatedDataLookup { "wacca:Single": "rate"; "pms:Controller": "sieglinde"; "pms:Keyboard": "sieglinde"; - "itg:Stamina": "blockRating" | "average32Speed"; + "itg:Stamina": "average32Speed" | "blockRating"; } export interface SessionDocument extends MongoDBDocument { userID: integer; sessionID: string; - scoreInfo: SessionScoreInfo[]; + scoreInfo: Array; name: string; desc: string | null; game: Game; playtype: Playtype; + // This field is allowed to be null for compatibility with kamaitachi1 sessions, where import types didn't exist. importType: ImportTypes | null; timeInserted: integer; @@ -520,20 +522,23 @@ export interface ImportDocument extends MongoDBDocument { userID: integer; timeStarted: number; timeFinished: number; + // Contains an array of IDStrings, which dictates what (game:playtype)s were involved in this import. - idStrings: IDStrings[]; + idStrings: Array; importID: string; - scoreIDs: string[]; + scoreIDs: Array; game: Game; - playtypes: Playtypes[Game][]; - errors: ImportErrContent[]; + playtypes: Array; + errors: Array; + // For performance reasons, imports only show what sessions they created, rather than what sessions they didn't. // This is just an array of sessionIDs, to keep things normalised. May be empty. - createdSessions: SessionInfoReturn[]; + createdSessions: Array; importType: ImportTypes; - classDeltas: ClassDelta[]; - goalInfo: GoalImportInfo[]; - milestoneInfo: MilestoneImportInfo[]; + classDeltas: Array; + goalInfo: Array; + milestoneInfo: Array; + /** * Whether the user deliberately imported this through an action (i.e. uploaded a file personally) [true] * or was imported on their behalf through a service (i.e. fervidex) @@ -545,11 +550,13 @@ export interface ImportTimingsDocument { importID: string; timestamp: number; total: number; + /** * Relative times - these are the times for each section * divided by how much data they had to process. */ - rel: Omit; + rel: Omit; + /** * Absolute times - these are the times for each section. */ @@ -569,7 +576,7 @@ interface ImportTimingSections { export type GoalImportStat = Pick< GoalSubscriptionDocument, - "progress" | "progressHuman" | "outOf" | "outOfHuman" | "achieved" + "achieved" | "outOf" | "outOfHuman" | "progress" | "progressHuman" >; export interface GoalImportInfo { @@ -578,7 +585,7 @@ export interface GoalImportInfo { new: GoalImportStat; } -export type MilestoneImportStat = Pick; +export type MilestoneImportStat = Pick; export interface MilestoneImportInfo { milestoneID: string; @@ -599,14 +606,14 @@ export type GoalSubscriptionDocument = MongoDBDocument & { outOfHuman: string; wasInstantlyAchieved: boolean; } & ( - | { - achieved: true; - timeAchieved: integer; - } | { achieved: false; timeAchieved: null; } + | { + achieved: true; + timeAchieved: integer; + } ); interface MilestoneGoalReference { @@ -617,21 +624,22 @@ interface MilestoneGoalReference { interface MilestoneSection { title: string; desc: string; - goals: MilestoneGoalReference[]; + goals: Array; } export interface MilestoneDocument extends MongoDBDocument { game: Game; playtype: Playtype; + /** * all: All goals must be achieved in order for the milestone to be complete * abs: Goals achieved must be greater than or equal to criteria.value. * proportion: Goals achieved must be greater than or equal to criteria.value * total_goals. */ - criteria: MilestoneAllCriteria | MilestoneAbsPropCriteria; + criteria: MilestoneAbsPropCriteria | MilestoneAllCriteria; name: string; desc: string; - milestoneData: MilestoneSection[]; + milestoneData: Array; milestoneID: string; } @@ -650,16 +658,16 @@ export interface MilestoneSetDocument extends MongoDBDocument { desc: string; game: Game; playtype: Playtype; - milestones: string[]; + milestones: Array; } -export type UserBadges = "alpha" | "beta" | "dev-team" | "contributor" | "significant-contributor"; +export type UserBadges = "alpha" | "beta" | "contributor" | "dev-team" | "significant-contributor"; export enum UserAuthLevels { - BANNED, - USER, - MOD, - ADMIN, + BANNED = 0, + USER = 1, + MOD = 2, + ADMIN = 3, } export interface PublicUserDocument extends MongoDBDocument { @@ -681,7 +689,7 @@ export interface PublicUserDocument extends MongoDBDocument { customPfpLocation: string | null; customBannerLocation: string | null; clan: string | null; // todo - badges: UserBadges[]; + badges: Array; authLevel: UserAuthLevels; } @@ -692,20 +700,20 @@ export interface UGSRatingsLookup { "sdvx:Single": "VF6"; "usc:Keyboard": "VF6"; "usc:Controller": "VF6"; - "ddr:SP": "MFCP" | "ktRating"; - "ddr:DP": "MFCP" | "ktRating"; + "ddr:SP": "ktRating" | "MFCP"; + "ddr:DP": "ktRating" | "MFCP"; "maimai:Single": "ktRating"; "jubeat:Single": "jubility" | "naiveJubility"; "museca:Single": "ktRating"; "bms:7K": "sieglinde"; "bms:14K": "sieglinde"; "chunithm:Single": "naiveRating"; - "gitadora:Gita": "skill" | "naiveSkill"; - "gitadora:Dora": "skill" | "naiveSkill"; + "gitadora:Gita": "naiveSkill" | "skill"; + "gitadora:Dora": "naiveSkill" | "skill"; "wacca:Single": "naiveRate" | "rate"; "pms:Controller": "sieglinde"; "pms:Keyboard": "sieglinde"; - "itg:Stamina": "highestBlock" | "highest32" | "highest256"; + "itg:Stamina": "highest32" | "highest256" | "highestBlock"; } export interface UserGameStats extends MongoDBDocument { @@ -717,51 +725,51 @@ export interface UserGameStats extends MongoDBD } type SupportedIIDXVersions = + | "3-cs" + | "4-cs" + | "5-cs" + | "6-cs" + | "7-cs" + | "8-cs" + | "9-cs" + | "10-cs" + | "11-cs" + | "12-cs" + | "13-cs" + | "14-cs" + | "15-cs" + | "16-cs" + | "20" + | "21" + | "22" + | "23" + | "24" + | "25" + | "26-omni" | "26" + | "27-2dxtra" + | "27-omni" | "27" + | "28-2dxtra" + | "28-omni" + | "28-omni" | "28" | "29" - | "28-omni" - | "27-omni" - | "28-omni" - | "25" - | "24" - | "23" - | "22" - | "21" - | "20" - | "inf" - | "27-2dxtra" - | "28-2dxtra" | "bmus" - | "26-omni" - | "16-cs" - | "15-cs" - | "14-cs" - | "13-cs" - | "12-cs" - | "11-cs" - | "10-cs" - | "9-cs" - | "8-cs" - | "7-cs" - | "6-cs" - | "5-cs" - | "4-cs" - | "3-cs"; + | "inf"; export interface GPTSupportedVersions { "iidx:SP": SupportedIIDXVersions; "iidx:DP": SupportedIIDXVersions; "popn:9B": "peace"; - "sdvx:Single": "booth" | "inf" | "gw" | "heaven" | "vivid" | "exceed" | "konaste"; + "sdvx:Single": "booth" | "exceed" | "gw" | "heaven" | "inf" | "konaste" | "vivid"; "usc:Controller": never; "usc:Keyboard": never; "ddr:SP": "a20"; "ddr:DP": "a20"; "maimai:Single": "finale"; "jubeat:Single": "clan" | "festo"; - "museca:Single": "1.5" | "1.5-b"; + "museca:Single": "1.5-b" | "1.5"; "bms:7K": never; "bms:14K": never; "chunithm:Single": "paradiselost"; @@ -775,7 +783,7 @@ export interface GPTSupportedVersions { interface CDDataIIDXSP { notecount: integer; - inGameID: integer | integer[]; + inGameID: Array | integer; arcChartID: string | null; hashSHA256: string | null; "2dxtraSet": string | null; @@ -793,7 +801,7 @@ interface CDDataPMS { notecount: integer; hashMD5: string; hashSHA256: string; - tableFolders: { table: string; level: string }[]; + tableFolders: Array<{ table: string; level: string }>; } type CDDataBMS = CDDataPMS & { @@ -801,10 +809,10 @@ type CDDataBMS = CDDataPMS & { }; interface CDDataUSC { - hashSHA1: string | string[]; + hashSHA1: Array | string; isOfficial: boolean; effector: string; - tableFolders: { table: string; level: string }[]; + tableFolders: Array<{ table: string; level: string }>; } interface ChartDocumentData { @@ -833,7 +841,7 @@ interface ChartDocumentData { "pms:Keyboard": CDDataPMS; "itg:Stamina": { chartHash: string; - difficultyTag: "Beginner" | "Easy" | "Medium" | "Hard" | "Challenge"; + difficultyTag: "Beginner" | "Challenge" | "Easy" | "Hard" | "Medium"; breakdown: { detailed: string; partiallySimplified: string; @@ -856,10 +864,10 @@ interface ChartDocumentData { } export interface GPTTierlists { - "iidx:SP": "kt-HC" | "kt-NC" | "kt-EXHC"; + "iidx:SP": "kt-EXHC" | "kt-HC" | "kt-NC"; "iidx:DP": "dp-tier"; - "bms:7K": "sgl-HC" | "sgl-EC"; - "bms:14K": "sgl-HC" | "sgl-EC"; + "bms:7K": "sgl-EC" | "sgl-HC"; + "bms:14K": "sgl-EC" | "sgl-HC"; "popn:9B": never; "sdvx:Single": "clear"; "usc:Keyboard": never; @@ -873,8 +881,8 @@ export interface GPTTierlists { "gitadora:Gita": never; "gitadora:Dora": never; "wacca:Single": never; - "pms:Controller": "sgl-HC" | "sgl-EC"; - "pms:Keyboard": "sgl-HC" | "sgl-EC"; + "pms:Controller": "sgl-EC" | "sgl-HC"; + "pms:Keyboard": "sgl-EC" | "sgl-HC"; "itg:Stamina": never; } @@ -895,7 +903,7 @@ export interface ChartDocument extends MongoDBD playtype: IDStringToPlaytype[I]; data: ChartDocumentData[I]; tierlistInfo: Partial>; - versions: GPTSupportedVersions[I][]; + versions: Array; } interface SongDocumentData { @@ -941,8 +949,8 @@ export interface SongDocument extends MongoDBDocument { id: integer; title: string; artist: string; - searchTerms: string[]; - altTitles: string[]; + searchTerms: Array; + altTitles: Array; data: SongDocumentData[G]; } @@ -952,7 +960,7 @@ export interface TableDocument extends MongoDBDocument { playtype: Playtype; title: string; description: string; - folders: string[]; + folders: Array; inactive: boolean; default: boolean; } @@ -962,12 +970,13 @@ export interface BaseFolderDocument extends MongoDBDocument { game: Game; playtype: Playtype; folderID: string; + /** * This folder has been superceded by another folder, * such as one on a more modern version of the game. */ inactive: boolean; - searchTerms: string[]; + searchTerms: Array; } export interface FolderSongsDocument extends BaseFolderDocument { @@ -982,10 +991,10 @@ export interface FolderChartsDocument extends BaseFolderDocument { export interface FolderStaticDocument extends BaseFolderDocument { type: "static"; - data: string[]; + data: Array; } -export type FolderDocument = FolderStaticDocument | FolderChartsDocument | FolderSongsDocument; +export type FolderDocument = FolderChartsDocument | FolderSongsDocument | FolderStaticDocument; export interface FolderChartLookup extends MongoDBDocument { chartID: string; @@ -1002,41 +1011,41 @@ export type MilestoneSubscriptionDocument = MongoDBDocument & { lastInteraction: integer | null; wasInstantlyAchieved: boolean; } & ( - | { - achieved: true; - timeAchieved: integer; - } | { achieved: false; timeAchieved: null; } + | { + achieved: true; + timeAchieved: integer; + } ); -type RanOptions = "NONRAN" | "RANDOM" | "R-RANDOM" | "S-RANDOM" | "MIRROR"; +type RanOptions = "MIRROR" | "NONRAN" | "R-RANDOM" | "RANDOM" | "S-RANDOM"; interface IIDXSPScoreMeta { random: RanOptions | null; - assist: "NO ASSIST" | "AUTO SCRATCH" | "LEGACY NOTE" | "FULL ASSIST" | null; - range: "NONE" | "SUDDEN+" | "HIDDEN+" | "SUD+ HID+" | "LIFT" | "LIFT SUD+" | null; - gauge: "ASSISTED EASY" | "EASY" | "NORMAL" | "HARD" | "EX-HARD" | null; + assist: "AUTO SCRATCH" | "FULL ASSIST" | "LEGACY NOTE" | "NO ASSIST" | null; + range: "HIDDEN+" | "LIFT SUD+" | "LIFT" | "NONE" | "SUD+ HID+" | "SUDDEN+" | null; + gauge: "ASSISTED EASY" | "EASY" | "EX-HARD" | "HARD" | "NORMAL" | null; } interface BMS7KScoreMeta { random: RanOptions | null; - inputDevice: "KEYBOARD" | "BM_CONTROLLER" | null; + inputDevice: "BM_CONTROLLER" | "KEYBOARD" | null; client: "LR2" | "lr2oraja" | null; - gauge: "NORMAL" | "EASY" | "HARD" | "EX-HARD" | null; + gauge: "EASY" | "EX-HARD" | "HARD" | "NORMAL" | null; } interface PMSScoreMeta { random: RanOptions | null; client: "beatoraja" | null; - gauge: "NORMAL" | "EASY" | "HARD" | "EX-HARD" | null; + gauge: "EASY" | "EX-HARD" | "HARD" | "NORMAL" | null; } interface USCScoreMeta { - noteMod: "NORMAL" | "MIRROR" | "RANDOM" | "MIR-RAN" | null; - gaugeMod: "NORMAL" | "HARD" | "PERMISSIVE" | null; + noteMod: "MIR-RAN" | "MIRROR" | "NORMAL" | "RANDOM" | null; + gaugeMod: "HARD" | "NORMAL" | "PERMISSIVE" | null; } interface ScoreMetaLookup { @@ -1048,8 +1057,8 @@ interface ScoreMetaLookup { hiSpeed: number | null; hidden: integer | null; sudden: integer | null; - random: "NONRAN" | "MIRROR" | "RANDOM" | "S-RANDOM" | null; - gauge: "NORMAL" | "EASY" | "HARD" | "DANGER" | null; + random: "MIRROR" | "NONRAN" | "RANDOM" | "S-RANDOM" | null; + gauge: "DANGER" | "EASY" | "HARD" | "NORMAL" | null; }; "sdvx:Single": { inSkillAnalyser: boolean | null }; "usc:Controller": USCScoreMeta; @@ -1081,27 +1090,26 @@ interface BASE_VALID_HIT_META { type IIDXHitMeta = BASE_VALID_HIT_META & { bp: integer | null; gauge: number | null; - gaugeHistory: (number | null)[] | null; - scoreHistory: number[] | null; + gaugeHistory: Array | null; + scoreHistory: Array | null; comboBreak: integer | null; gsm: { - EASY: (number | null)[]; - NORMAL: (number | null)[]; - HARD: (number | null)[]; - EX_HARD: (number | null)[]; + EASY: Array; + NORMAL: Array; + HARD: Array; + EX_HARD: Array; } | null; }; -type BMSJudgePermutations = `${"e" | "l"}${"bd" | "pr" | "gd" | "gr" | "pg"}`; +type BMSJudgePermutations = `${"e" | "l"}${"bd" | "gd" | "gr" | "pg" | "pr"}`; -type BMSHitMeta = BASE_VALID_HIT_META & - { - [K in BMSJudgePermutations]: integer; - } & { - bp: integer | null; - gauge: number | null; - gaugeHistory: number[] | null; - }; +type BMSHitMeta = BASE_VALID_HIT_META & { + [K in BMSJudgePermutations]: integer; +} & { + bp: integer | null; + gauge: number | null; + gaugeHistory: Array | null; +}; export type USCHitMeta = BASE_VALID_HIT_META & { gauge: number | null; @@ -1113,13 +1121,13 @@ export interface HitMetaLookup { "popn:9B": BASE_VALID_HIT_META & { gauge: number | null; specificClearType: - | "failedCircle" - | "failedDiamond" - | "failedStar" - | "easyClear" | "clearCircle" | "clearDiamond" | "clearStar" + | "easyClear" + | "failedCircle" + | "failedDiamond" + | "failedStar" | "fullComboCircle" | "fullComboDiamond" | "fullComboStar" @@ -1150,35 +1158,35 @@ export interface HitMetaLookup { }; } -type IIDXJudges = "pgreat" | "great" | "good" | "bad" | "poor"; -type DDRJudges = "marvelous" | "perfect" | "great" | "good" | "boo" | "miss" | "ok" | "ng"; -type GitadoraJudges = "perfect" | "great" | "good" | "ok" | "miss"; +type IIDXJudges = "bad" | "good" | "great" | "pgreat" | "poor"; +type DDRJudges = "boo" | "good" | "great" | "marvelous" | "miss" | "ng" | "ok" | "perfect"; +type GitadoraJudges = "good" | "great" | "miss" | "ok" | "perfect"; // judges might need to be changed here... // @bug Known that sdvx calls misses errors. I, however, don't care. -type SDVXJudges = "critical" | "near" | "miss"; +type SDVXJudges = "critical" | "miss" | "near"; export interface JudgementLookup { "iidx:SP": IIDXJudges; "iidx:DP": IIDXJudges; - "popn:9B": "cool" | "great" | "good" | "bad"; + "popn:9B": "bad" | "cool" | "good" | "great"; "sdvx:Single": SDVXJudges; "usc:Controller": SDVXJudges; "usc:Keyboard": SDVXJudges; "ddr:SP": DDRJudges; "ddr:DP": DDRJudges; - "maimai:Single": "perfect" | "great" | "good" | "miss"; - "jubeat:Single": "perfect" | "great" | "good" | "poor" | "miss"; - "museca:Single": "critical" | "near" | "miss"; + "maimai:Single": "good" | "great" | "miss" | "perfect"; + "jubeat:Single": "good" | "great" | "miss" | "perfect" | "poor"; + "museca:Single": "critical" | "miss" | "near"; "bms:7K": IIDXJudges; "bms:14K": IIDXJudges; - "chunithm:Single": "jcrit" | "justice" | "attack" | "miss"; + "chunithm:Single": "attack" | "jcrit" | "justice" | "miss"; "gitadora:Gita": GitadoraJudges; "gitadora:Dora": GitadoraJudges; - "wacca:Single": "marvelous" | "great" | "good" | "miss"; - "pms:Controller": "cool" | "great" | "good" | "bad" | "poor"; - "pms:Keyboard": "cool" | "great" | "good" | "bad" | "poor"; - "itg:Stamina": "fantastic" | "excellent" | "great" | "decent" | "wayoff" | "miss"; + "wacca:Single": "good" | "great" | "marvelous" | "miss"; + "pms:Controller": "bad" | "cool" | "good" | "great" | "poor"; + "pms:Keyboard": "bad" | "cool" | "good" | "great" | "poor"; + "itg:Stamina": "decent" | "excellent" | "fantastic" | "great" | "miss" | "wayoff"; } export interface ScoreCalculatedDataLookup { @@ -1188,8 +1196,8 @@ export interface ScoreCalculatedDataLookup { "sdvx:Single": "VF6"; "usc:Keyboard": "VF6"; "usc:Controller": "VF6"; - "ddr:SP": "MFCP" | "ktRating"; - "ddr:DP": "MFCP" | "ktRating"; + "ddr:SP": "ktRating" | "MFCP"; + "ddr:DP": "ktRating" | "MFCP"; "maimai:Single": "ktRating"; "jubeat:Single": "jubility"; "museca:Single": "ktRating"; @@ -1242,7 +1250,7 @@ export interface PBScoreDocument extends MongoD composedFrom: { scorePB: string; lampPB: string; - other?: PBScoreComposedReference[]; + other?: Array; }; rankingData: { rank: integer; @@ -1271,33 +1279,33 @@ export interface PBScoreDocument extends MongoD } export type FileUploadImportTypes = + | "file/batch-manual" | "file/eamusement-iidx-csv" | "file/eamusement-sdvx-csv" - | "file/batch-manual" - | "file/solid-state-squad" | "file/mer-iidx" - | "file/pli-iidx-csv"; + | "file/pli-iidx-csv" + | "file/solid-state-squad"; export type APIImportTypes = - | "api/flo-iidx" - | "api/flo-sdvx" + | "api/arc-iidx" + | "api/arc-sdvx" | "api/eag-iidx" | "api/eag-sdvx" - | "api/min-sdvx" - | "api/arc-iidx" - | "api/arc-sdvx"; + | "api/flo-iidx" + | "api/flo-sdvx" + | "api/min-sdvx"; export type IRImportTypes = - | "ir/direct-manual" | "ir/barbatos" - | "ir/fervidex" - | "ir/usc" | "ir/beatoraja" + | "ir/direct-manual" | "ir/fervidex-static" + | "ir/fervidex" | "ir/kshook-sv6c" - | "ir/lr2hook"; + | "ir/lr2hook" + | "ir/usc"; -export type ImportTypes = FileUploadImportTypes | IRImportTypes | APIImportTypes; +export type ImportTypes = APIImportTypes | FileUploadImportTypes | IRImportTypes; export interface ImportProcessInfoKTDataNotFound { success: false; @@ -1343,11 +1351,11 @@ export interface ImportProcessInfoInternalError { } export type ImportProcessingInfo = + | ImportProcessInfoInternalError + | ImportProcessInfoInvalidDatapoint | ImportProcessInfoKTDataNotFound | ImportProcessInfoOrphanExists - | ImportProcessInfoScoreImported - | ImportProcessInfoInvalidDatapoint - | ImportProcessInfoInternalError; + | ImportProcessInfoScoreImported; export interface ImportStatistics { scoreCount: integer; @@ -1362,7 +1370,7 @@ export interface KaiAuthDocument { userID: integer; token: string; refreshToken: string; - service: "FLO" | "EAG" | "MIN"; + service: "EAG" | "FLO" | "MIN"; } /** @@ -1371,7 +1379,7 @@ export interface KaiAuthDocument { export interface BMSCourseDocument { title: string; md5sums: string; - set: "genocideDan" | "stslDan" | "lnDan" | "scratchDan"; + set: "genocideDan" | "lnDan" | "scratchDan" | "stslDan"; playtype: "7K" | "14K"; value: integer; } @@ -1380,13 +1388,13 @@ export interface BMSCourseDocument { * All the permissions a token may have. */ export type APIPermissions = - | "submit_score" | "customise_profile" - | "customise_session" | "customise_score" + | "customise_session" | "delete_score" + | "manage_rivals" | "manage_targets" - | "manage_rivals"; + | "submit_score"; /** * Information about the API Token used to make this request. @@ -1396,6 +1404,7 @@ export interface APITokenDocument extends MongoDBDocument { token: string | null; identifier: string; permissions: Partial>; + // API Tokens may be created as a result of a Tachi Client flow. This prop optionally // stores that. fromAPIClient: string | null; @@ -1405,19 +1414,19 @@ export interface ImportLockDocument extends MongoDBDocument { userID: integer; } -export type ShowcaseStatDetails = ShowcaseStatFolder | ShowcaseStatChart; +export type ShowcaseStatDetails = ShowcaseStatChart | ShowcaseStatFolder; export interface ShowcaseStatFolder { mode: "folder"; folderID: string; - property: "score" | "percent" | "grade" | "lamp"; + property: "grade" | "lamp" | "percent" | "score"; gte: number; } export interface ShowcaseStatChart { mode: "chart"; chartID: string; - property: "score" | "percent" | "grade" | "lamp" | "playcount"; + property: "grade" | "lamp" | "percent" | "playcount" | "score"; } export interface UGPTSpecificPreferences { @@ -1451,12 +1460,12 @@ export interface UGPTSettings extends MongoDBDo preferredScoreAlg: ScoreCalculatedDataLookup[I] | null; preferredSessionAlg: SessionCalculatedDataLookup[I] | null; preferredProfileAlg: UGSRatingsLookup[I] | null; - stats: ShowcaseStatDetails[]; + stats: Array; scoreBucket: "grade" | "lamp" | null; defaultTable: string | null; gameSpecific: UGPTSpecificPreferences[I]; }; - rivals: integer[]; + rivals: Array; } export interface UserGameStatsSnapshot @@ -1485,12 +1494,12 @@ export type BatchManualScore = { scoreMeta?: Partial; } & ( | { - matchType: "tachiSongID" | "inGameID" | "songTitle" | "ddrSongHash"; - difficulty: Difficulties[I]; + matchType: "bmsChartHash" | "itgChartHash" | "popnChartHash" | "uscChartHash"; + difficulty?: undefined; // hack to stop ts from screaming when this is accessed sometimes } | { - matchType: "bmsChartHash" | "uscChartHash" | "popnChartHash" | "itgChartHash"; - difficulty?: undefined; // hack to stop ts from screaming when this is accessed sometimes + matchType: "ddrSongHash" | "inGameID" | "songTitle" | "tachiSongID"; + difficulty: Difficulties[I]; } ); @@ -1501,7 +1510,7 @@ export interface BatchManual { service: string; version?: GPTSupportedVersions[I]; }; - scores: BatchManualScore[]; + scores: Array>; classes?: Record | null; } @@ -1521,16 +1530,16 @@ export interface TachiAPIClientDocument { clientSecret: string; name: string; author: integer; - requestedPermissions: APIPermissions[]; - redirectUri: null | string; - webhookUri: null | string; - apiKeyTemplate: null | string; - apiKeyFilename: null | string; + requestedPermissions: Array; + redirectUri: string | null; + webhookUri: string | null; + apiKeyTemplate: string | null; + apiKeyFilename: string | null; } export interface FervidexSettingsDocument { userID: integer; - cards: string[] | null; + cards: Array | null; forceStaticImport: boolean; } @@ -1538,14 +1547,14 @@ export interface OrphanChart { idString: I; chartDoc: ChartDocument; songDoc: SongDocument; - userIDs: integer[]; + userIDs: Array; } export interface ClassAchievementDocument extends MongoDBDocument { game: IDStringToGame[I]; playtype: IDStringToPlaytype[I]; classSet: AllClassSets; - classOldValue: null | integer; + classOldValue: integer | null; classValue: integer; timeAchieved: number; userID: integer; @@ -1562,6 +1571,7 @@ export interface RecentlyViewedFolderDocument { interface BaseNotification { title: string; notifID: string; + // The user this notification was sent to. sentTo: integer; sentAt: integer; @@ -1570,20 +1580,18 @@ interface BaseNotification { export type NotificationBody = | { - // Emitted when the user is rivalled by someone. - type: "RIVALED_BY"; + type: "MILESTONE_CHANGED"; // Emitted when a milestone the user is subscribed to changed. + content: { + milestoneID: string; + }; + } + | { + type: "RIVALED_BY"; // Emitted when the user is rivalled by someone. content: { userID: integer; game: Game; playtype: Playtype; }; - } - | { - // Emitted when a milestone the user is subscribed to changed. - type: "MILESTONE_CHANGED"; - content: { - milestoneID: string; - }; }; export type NotificationDocument = BaseNotification & { diff --git a/common/src/utils/util.ts b/common/src/utils/util.ts index 951f302c3..ecc1642cc 100644 --- a/common/src/utils/util.ts +++ b/common/src/utils/util.ts @@ -1,6 +1,6 @@ -import { ChartDocument, SongDocument, Game, IDStrings, Playtypes } from ".."; import { GetGameConfig, GetGamePTConfig } from "../config/config"; -import { Grades, integer } from "../types"; +import type { ChartDocument, SongDocument, Game, IDStrings, Playtypes } from ".."; +import type { Grades, integer } from "../types"; export function FormatInt(v: number): string { return v.toString(); @@ -9,6 +9,7 @@ export function FormatInt(v: number): string { export function FormatDifficulty(chart: ChartDocument, game: Game): string { if (game === "bms" || game === "pms") { const bmsChart = chart as ChartDocument<"bms:7K" | "bms:14K">; + return ( bmsChart.data.tableFolders.map((e) => `${e.table}${e.level}`).join(", ") || "Unrated" ); @@ -70,11 +71,7 @@ export function FormatGame(game: Game, playtype: Playtypes[Game]): string { return `${gameConfig.name} (${playtype})`; } -export function FormatChart( - game: Game, - song: SongDocument, - chart: ChartDocument -): string { +export function FormatChart(game: Game, song: SongDocument, chart: ChartDocument): string { if (game === "bms") { const tables = (chart as ChartDocument<"bms:7K" | "bms:14K">).data.tableFolders; @@ -83,11 +80,11 @@ export function FormatChart( let realTitle = bmsSong.title; if (bmsSong.data.subtitle) { - realTitle += ` - ${bmsSong.data.subtitle}`; + realTitle = `${realTitle} - ${bmsSong.data.subtitle}`; } if (bmsSong.data.genre) { - realTitle += ` [${bmsSong.data.genre}]`; + realTitle = `${realTitle} [${bmsSong.data.genre}]`; } if (tables.length === 0) { @@ -96,24 +93,22 @@ export function FormatChart( return `${realTitle} (${tables.map((e) => `${e.table}${e.level}`).join(", ")})`; } else if (game === "usc") { - const uscChart = chart as ChartDocument<"usc:Keyboard" | "usc:Controller">; - - const tables = Object.entries(uscChart.data.tableFolders); + const uscChart = chart as ChartDocument<"usc:Controller" | "usc:Keyboard">; // If this chart isn't an official, render it differently if (!uscChart.data.isOfficial) { // Same as BMS. turn this into SongTitle (Keyboard MXM normal1, insane2) - return `${song.title} (${chart.playtype} ${chart.difficulty} ${tables - .map((e) => `${e[0]}${e[1]}`) - .join(", ")})`; - } else if (uscChart.data.isOfficial && tables.length !== 0) { + return `${song.title} (${chart.playtype} ${ + chart.difficulty + } ${uscChart.data.tableFolders.map((e) => `${e.table}${e.level}`).join(", ")})`; + } else if (uscChart.data.tableFolders.length !== 0) { // if this chart is an official **AND** is on tables (unlikely), render // it as so: // SongTitle (Keyboard MXM 17, normal1, insane2) return `${song.title} (${chart.playtype} ${chart.difficulty} ${ chart.level - }, ${tables.map((e) => `${e[0]}${e[1]}`).join(", ")})`; + }, ${uscChart.data.tableFolders.map((e) => `${e.table}${e.level}`).join(", ")})`; } // otherwise, it's just an official and should be rendered like any other game. @@ -231,6 +226,7 @@ export function GenericFormatGradeDelta( export function FormatSieglindeBMS(sgl: number): string { const fixedSgl = sgl.toFixed(2); + if (sgl < 13) { return `${fixedSgl} (☆${fixedSgl})`; } @@ -240,6 +236,7 @@ export function FormatSieglindeBMS(sgl: number): string { export function FormatSieglindePMS(sgl: number): string { const fixedSgl = sgl.toFixed(2); + if (sgl < 13) { return `${fixedSgl} (○${fixedSgl})`; } diff --git a/common/src/webhooks.ts b/common/src/webhooks.ts index 0821887c8..0ec6b58a0 100644 --- a/common/src/webhooks.ts +++ b/common/src/webhooks.ts @@ -1,6 +1,6 @@ -import { Game, Playtypes } from "."; -import { GameClassSets } from "./game-classes"; -import { GoalImportStat, IDStrings, integer, MilestoneImportStat } from "./types"; +import type { Game, Playtypes } from "."; +import type { GameClassSets } from "./game-classes"; +import type { GoalImportStat, IDStrings, integer, MilestoneImportStat } from "./types"; /** * An event fired when a users class improves. @@ -25,12 +25,12 @@ export interface WebhookEventGoalAchievedV1 { content: { userID: integer; game: Game; - goals: { + goals: Array<{ goalID: string; old: GoalImportStat; new: GoalImportStat; playtype: Playtypes[Game]; - }[]; + }>; }; } diff --git a/common/tsconfig.json b/common/tsconfig.json index 99012a420..1a691c5ea 100644 --- a/common/tsconfig.json +++ b/common/tsconfig.json @@ -16,10 +16,10 @@ "sourceMap": true }, "include": [ - "src/**/*.ts" + "src/**/*.ts", + "src/**/*.test.ts" ], "exclude": [ - "src/**/*.test.ts", "src/legacy/**/*.ts" ] } \ No newline at end of file