From df1c968b96b19d9504521f1c4881d2f8ca14f596 Mon Sep 17 00:00:00 2001 From: johngrantuk Date: Wed, 24 Jul 2024 10:51:06 +0100 Subject: [PATCH 1/5] chore: Change to use prettier and eslint. --- typescript/.eslintignore | 2 + typescript/.eslintrc.js | 8 + typescript/.prettierrc | 7 + typescript/biome.json | 47 --- typescript/package.json | 13 +- typescript/pnpm-lock.yaml | 743 +++++++++++++++++++++++++++++++++----- 6 files changed, 678 insertions(+), 142 deletions(-) create mode 100644 typescript/.eslintignore create mode 100644 typescript/.eslintrc.js create mode 100644 typescript/.prettierrc delete mode 100644 typescript/biome.json diff --git a/typescript/.eslintignore b/typescript/.eslintignore new file mode 100644 index 0000000..f06235c --- /dev/null +++ b/typescript/.eslintignore @@ -0,0 +1,2 @@ +node_modules +dist diff --git a/typescript/.eslintrc.js b/typescript/.eslintrc.js new file mode 100644 index 0000000..2e84111 --- /dev/null +++ b/typescript/.eslintrc.js @@ -0,0 +1,8 @@ +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint', 'prettier'], + extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'], + rules: { + }, +}; diff --git a/typescript/.prettierrc b/typescript/.prettierrc new file mode 100644 index 0000000..c3fc280 --- /dev/null +++ b/typescript/.prettierrc @@ -0,0 +1,7 @@ +{ + "printWidth": 80, + "tabWidth": 4, + "singleQuote": true, + "bracketSpacing": true, + "semi": true +} diff --git a/typescript/biome.json b/typescript/biome.json deleted file mode 100644 index 5d2eb7a..0000000 --- a/typescript/biome.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "$schema": "https://biomejs.dev/schemas/1.4.1/schema.json", - "files": { - "ignore": ["./node_modules", "dist", "pnpm-lock.yaml", "./local"] - }, - "organizeImports": { - "ignore": ["."] - }, - "formatter": { - "enabled": true, - "indentStyle": "space", - "indentWidth": 4, - "lineWidth": 80 - }, - "linter": { - "enabled": true, - "rules": { - "recommended": true, - "correctness": { - "noUnusedVariables": "error" - }, - "complexity": { - "noForEach": "off", - "noStaticOnlyClass": "off" - }, - "performance": { - "noDelete": "off" - }, - "style": { - "noNonNullAssertion": "off", - "useShorthandArrayType": "error", - "noUselessElse": "off" - }, - "suspicious": { - "noArrayIndexKey": "off", - "noExplicitAny": "off" - } - } - }, - "javascript": { - "formatter": { - "quoteStyle": "single", - "trailingComma": "all", - "semicolons": "always" - } - } -} diff --git a/typescript/package.json b/typescript/package.json index bd2a14a..18e4253 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -19,20 +19,25 @@ ], "scripts": { "build": "tsup", - "format": "biome format --write .", - "lint": "dpdm -T ./src && biome check .", - "lint:fix": "biome check . --apply", + "format": "prettier --config .prettierrc 'src/**/*.ts' --write", + "lint": "dpdm -T ./src && eslint ./src --ext .ts", + "lint:fix": "eslint ./src --ext .ts --fix", "test": "vitest dev", "test:ci": "vitest run", "changeset": "changeset", "changeset:release": "pnpm build && changeset publish" }, "devDependencies": { - "@biomejs/biome": "^1.5.2", "@changesets/cli": "^2.27.1", "@types/node": "^18.19.7", + "@typescript-eslint/eslint-plugin": "^7.17.0", + "@typescript-eslint/parser": "^7.17.0", "dotenv": "^16.3.1", "dpdm": "^3.14.0", + "eslint": "^8.56.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.2.1", + "prettier": "^3.3.3", "ts-node": "^10.9.2", "tsup": "^8.0.1", "typescript": "^5.3.3", diff --git a/typescript/pnpm-lock.yaml b/typescript/pnpm-lock.yaml index b992280..42c908f 100644 --- a/typescript/pnpm-lock.yaml +++ b/typescript/pnpm-lock.yaml @@ -5,21 +5,36 @@ settings: excludeLinksFromLockfile: false devDependencies: - '@biomejs/biome': - specifier: ^1.5.2 - version: 1.5.2 '@changesets/cli': specifier: ^2.27.1 version: 2.27.1 '@types/node': specifier: ^18.19.7 version: 18.19.7 + '@typescript-eslint/eslint-plugin': + specifier: ^7.17.0 + version: 7.17.0(@typescript-eslint/parser@7.17.0)(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/parser': + specifier: ^7.17.0 + version: 7.17.0(eslint@8.57.0)(typescript@5.3.3) dotenv: specifier: ^16.3.1 version: 16.3.1 dpdm: specifier: ^3.14.0 version: 3.14.0 + eslint: + specifier: ^8.56.0 + version: 8.57.0 + eslint-config-prettier: + specifier: ^9.1.0 + version: 9.1.0(eslint@8.57.0) + eslint-plugin-prettier: + specifier: ^5.2.1 + version: 5.2.1(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.3.3) + prettier: + specifier: ^3.3.3 + version: 3.3.3 ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@18.19.7)(typescript@5.3.3) @@ -68,94 +83,6 @@ packages: regenerator-runtime: 0.14.1 dev: true - /@biomejs/biome@1.5.2: - resolution: {integrity: sha512-LhycxGQBQLmfv6M3e4tMfn/XKcUWyduDYOlCEBrHXJ2mMth2qzYt1JWypkWp+XmU/7Hl2dKvrP4mZ5W44+nWZw==} - engines: {node: '>=14.*'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@biomejs/cli-darwin-arm64': 1.5.2 - '@biomejs/cli-darwin-x64': 1.5.2 - '@biomejs/cli-linux-arm64': 1.5.2 - '@biomejs/cli-linux-arm64-musl': 1.5.2 - '@biomejs/cli-linux-x64': 1.5.2 - '@biomejs/cli-linux-x64-musl': 1.5.2 - '@biomejs/cli-win32-arm64': 1.5.2 - '@biomejs/cli-win32-x64': 1.5.2 - dev: true - - /@biomejs/cli-darwin-arm64@1.5.2: - resolution: {integrity: sha512-3JVl08aHKsPyf0XL9SEj1lssIMmzOMAn2t1zwZKBiy/mcZdb0vuyMSTM5haMQ/90wEmrkYN7zux777PHEGrGiw==} - engines: {node: '>=14.*'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@biomejs/cli-darwin-x64@1.5.2: - resolution: {integrity: sha512-QAPW9rZb/AgucUx+ogMg+9eJNipQDqvabktC5Tx4Aqb/mFzS6eDqNP7O0SbGz3DtC5Y2LATEj6o6zKIQ4ZT+3w==} - engines: {node: '>=14.*'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@biomejs/cli-linux-arm64-musl@1.5.2: - resolution: {integrity: sha512-Z29SjaOyO4QfajplNXSjLx17S79oPN42D094zjE24z7C7p3NxvLhKLygtSP9emgaXkcoESe2chOzF4IrGy/rlg==} - engines: {node: '>=14.*'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@biomejs/cli-linux-arm64@1.5.2: - resolution: {integrity: sha512-fVLrUgIlo05rO4cNu+Py5EwwmXnXhWH+8KrNlWkr2weMYjq85SihUsuWWKpmqU+bUVR+m5gwfcIXZVWYVCJMHw==} - engines: {node: '>=14.*'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@biomejs/cli-linux-x64-musl@1.5.2: - resolution: {integrity: sha512-ZolquPEjWYUmGeERS8svHOOT7OXEeoriPnV8qptgWJmYF9EO9HUGRn1UtCvdVziDYK+u1A7PxjOdkY1B00ty5A==} - engines: {node: '>=14.*'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@biomejs/cli-linux-x64@1.5.2: - resolution: {integrity: sha512-ixqJtUHtF0ho1+1DTZQLAEwHGSqvmvHhAAFXZQoaSdABn+IcITYExlFVA3bGvASy/xtPjRhTx42hVwPtLwMHwg==} - engines: {node: '>=14.*'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@biomejs/cli-win32-arm64@1.5.2: - resolution: {integrity: sha512-DN4cXSAoFTdjOoh7f+JITj1uQgQSXt+1pVea9bFrpbgip+ZwkONqQq+jUcmFMMehbp9LuiVtNXFz/ReHn6FY7A==} - engines: {node: '>=14.*'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@biomejs/cli-win32-x64@1.5.2: - resolution: {integrity: sha512-YvWWXZmk936FdrXqc2jcP6rfsXsNBIs9MKBQQoVXIihwNNRiAaBD9Iwa/ouU1b7Zxq2zETgeuRewVJickFuVOw==} - engines: {node: '>=14.*'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - /@changesets/apply-release-plan@7.0.1: resolution: {integrity: sha512-aPdSq/R++HOyfEeBGjEe6LNG8gs0KMSyRETD/J2092OkNq8mOioAxyKjMbvVUdzgr/HTawzMOz7lfw339KnsCA==} dependencies: @@ -553,6 +480,65 @@ packages: dev: true optional: true + /@eslint-community/eslint-utils@4.4.0(eslint@8.57.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.57.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.11.0: + resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@2.1.4: + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js@8.57.0: + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@humanwhocodes/config-array@0.11.14: + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema@2.0.3: + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + dev: true + /@isaacs/cliui@8.0.2: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -657,6 +643,11 @@ packages: dev: true optional: true + /@pkgr/core@0.1.1: + resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + dev: true + /@rollup/rollup-android-arm-eabi@4.17.2: resolution: {integrity: sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==} cpu: [arm] @@ -831,6 +822,137 @@ packages: resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} dev: true + /@typescript-eslint/eslint-plugin@7.17.0(@typescript-eslint/parser@7.17.0)(eslint@8.57.0)(typescript@5.3.3): + resolution: {integrity: sha512-pyiDhEuLM3PuANxH7uNYan1AaFs5XE0zw1hq69JBvGvE7gSuEoQl1ydtEe/XQeoC3GQxLXyOVa5kNOATgM638A==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@eslint-community/regexpp': 4.11.0 + '@typescript-eslint/parser': 7.17.0(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/scope-manager': 7.17.0 + '@typescript-eslint/type-utils': 7.17.0(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/utils': 7.17.0(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 7.17.0 + eslint: 8.57.0 + graphemer: 1.4.0 + ignore: 5.3.1 + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@5.3.3) + typescript: 5.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/parser@7.17.0(eslint@8.57.0)(typescript@5.3.3): + resolution: {integrity: sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 7.17.0 + '@typescript-eslint/types': 7.17.0 + '@typescript-eslint/typescript-estree': 7.17.0(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 7.17.0 + debug: 4.3.4 + eslint: 8.57.0 + typescript: 5.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager@7.17.0: + resolution: {integrity: sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA==} + engines: {node: ^18.18.0 || >=20.0.0} + dependencies: + '@typescript-eslint/types': 7.17.0 + '@typescript-eslint/visitor-keys': 7.17.0 + dev: true + + /@typescript-eslint/type-utils@7.17.0(eslint@8.57.0)(typescript@5.3.3): + resolution: {integrity: sha512-XD3aaBt+orgkM/7Cei0XNEm1vwUxQ958AOLALzPlbPqb8C1G8PZK85tND7Jpe69Wualri81PLU+Zc48GVKIMMA==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 7.17.0(typescript@5.3.3) + '@typescript-eslint/utils': 7.17.0(eslint@8.57.0)(typescript@5.3.3) + debug: 4.3.4 + eslint: 8.57.0 + ts-api-utils: 1.3.0(typescript@5.3.3) + typescript: 5.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types@7.17.0: + resolution: {integrity: sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A==} + engines: {node: ^18.18.0 || >=20.0.0} + dev: true + + /@typescript-eslint/typescript-estree@7.17.0(typescript@5.3.3): + resolution: {integrity: sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 7.17.0 + '@typescript-eslint/visitor-keys': 7.17.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.4 + semver: 7.6.2 + ts-api-utils: 1.3.0(typescript@5.3.3) + typescript: 5.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils@7.17.0(eslint@8.57.0)(typescript@5.3.3): + resolution: {integrity: sha512-r+JFlm5NdB+JXc7aWWZ3fKSm1gn0pkswEwIYsrGPdsT2GjsRATAKXiNtp3vgAAO1xZhX8alIOEQnNMl3kbTgJw==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@typescript-eslint/scope-manager': 7.17.0 + '@typescript-eslint/types': 7.17.0 + '@typescript-eslint/typescript-estree': 7.17.0(typescript@5.3.3) + eslint: 8.57.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/visitor-keys@7.17.0: + resolution: {integrity: sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A==} + engines: {node: ^18.18.0 || >=20.0.0} + dependencies: + '@typescript-eslint/types': 7.17.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@ungap/structured-clone@1.2.0: + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + dev: true + /@vitest/expect@1.2.0: resolution: {integrity: sha512-H+2bHzhyvgp32o7Pgj2h9RTHN0pgYaoi26Oo3mE+dCi1PAqV31kIIVfTbqMO3Bvshd5mIrJLc73EwSRrbol9Lw==} dependencies: @@ -870,6 +992,14 @@ packages: pretty-format: 29.7.0 dev: true + /acorn-jsx@5.3.2(acorn@8.12.1): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.12.1 + dev: true + /acorn-walk@8.3.2: resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} engines: {node: '>=0.4.0'} @@ -881,6 +1011,21 @@ packages: hasBin: true dev: true + /acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + /ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -942,6 +1087,10 @@ packages: sprintf-js: 1.0.3 dev: true + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + /array-buffer-byte-length@1.0.1: resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} engines: {node: '>= 0.4'} @@ -1023,6 +1172,13 @@ packages: readable-stream: 3.6.2 dev: true + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + /brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} dependencies: @@ -1075,6 +1231,11 @@ packages: set-function-length: 1.2.2 dev: true + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + /camelcase-keys@6.2.2: resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} engines: {node: '>=8'} @@ -1209,6 +1370,10 @@ packages: engines: {node: '>= 6'} dev: true + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + /confbox@0.1.7: resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} dev: true @@ -1315,6 +1480,10 @@ packages: type-detect: 4.0.8 dev: true + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + /defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} dependencies: @@ -1361,6 +1530,13 @@ packages: path-type: 4.0.0 dev: true + /doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + /dotenv@16.3.1: resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} engines: {node: '>=12'} @@ -1541,18 +1717,146 @@ packages: engines: {node: '>=0.8.0'} dev: true + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /eslint-config-prettier@9.1.0(eslint@8.57.0): + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + dependencies: + eslint: 8.57.0 + dev: true + + /eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.3.3): + resolution: {integrity: sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '*' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + dependencies: + eslint: 8.57.0 + eslint-config-prettier: 9.1.0(eslint@8.57.0) + prettier: 3.3.3 + prettier-linter-helpers: 1.0.0 + synckit: 0.9.1 + dev: true + + /eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/regexpp': 4.11.0 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.0 + '@humanwhocodes/config-array': 0.11.14 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.1 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.12.1 + acorn-jsx: 5.3.2(acorn@8.12.1) + eslint-visitor-keys: 3.4.3 + dev: true + /esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} hasBin: true dev: true + /esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + /estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} dependencies: '@types/estree': 1.0.5 dev: true + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + /execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} @@ -1596,6 +1900,14 @@ packages: tmp: 0.0.33 dev: true + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + dev: true + /fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} @@ -1607,12 +1919,27 @@ packages: micromatch: 4.0.6 dev: true + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + /fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} dependencies: reusify: 1.0.4 dev: true + /file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.2.0 + dev: true + /fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -1643,6 +1970,19 @@ packages: pkg-dir: 4.2.0 dev: true + /flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + rimraf: 3.0.2 + dev: true + + /flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + dev: true + /for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} dependencies: @@ -1684,6 +2024,10 @@ packages: universalify: 0.1.2 dev: true + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + /fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1756,6 +2100,13 @@ packages: 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@10.3.15: resolution: {integrity: sha512-0c6RlJt1TICLyvJYIApxb8GsXoai0KUP7AxKKAtsYXdgJR1mGEUa7DgwShbdk1nly0PYoZj01xd4hzbq3fsjpw==} engines: {node: '>=16 || 14 >=14.18'} @@ -1768,6 +2119,25 @@ packages: path-scurry: 1.11.1 dev: true + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + /globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} @@ -1802,6 +2172,10 @@ packages: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} dev: true + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true + /hard-rejection@2.1.0: resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} engines: {node: '>=6'} @@ -1885,11 +2259,32 @@ packages: engines: {node: '>= 4'} dev: true + /import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + /indent-string@4.0.0: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} dev: true + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} dev: true @@ -2000,6 +2395,11 @@ packages: engines: {node: '>=0.12.0'} dev: true + /is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + dev: true + /is-plain-obj@1.1.0: resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} engines: {node: '>=0.10.0'} @@ -2108,10 +2508,29 @@ 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 + + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: true + /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} dev: true + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + /jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} optionalDependencies: @@ -2126,6 +2545,12 @@ packages: graceful-fs: 4.2.11 dev: true + /keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + dependencies: + json-buffer: 3.0.1 + dev: true + /kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} @@ -2136,6 +2561,14 @@ packages: engines: {node: '>=6'} dev: true + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + /lilconfig@3.1.1: resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==} engines: {node: '>=14'} @@ -2182,6 +2615,10 @@ packages: p-locate: 5.0.0 dev: true + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + /lodash.sortby@4.7.0: resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} dev: true @@ -2285,6 +2722,12 @@ packages: engines: {node: '>=4'} dev: true + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + /minimatch@9.0.4: resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} engines: {node: '>=16 || 14 >=14.17'} @@ -2338,6 +2781,10 @@ packages: hasBin: true dev: true + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + /normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} dependencies: @@ -2390,6 +2837,12 @@ packages: object-keys: 1.1.1 dev: true + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + /onetime@5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} @@ -2404,6 +2857,18 @@ packages: mimic-fn: 4.0.0 dev: true + /optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + dev: true + /ora@5.4.1: resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} engines: {node: '>=10'} @@ -2480,6 +2945,13 @@ packages: engines: {node: '>=6'} dev: true + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + /parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} @@ -2495,6 +2967,11 @@ packages: engines: {node: '>=8'} dev: true + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + /path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -2610,12 +3087,30 @@ packages: which-pm: 2.0.0 dev: true + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + dependencies: + fast-diff: 1.3.0 + dev: true + /prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} engines: {node: '>=10.13.0'} hasBin: true dev: true + /prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} + hasBin: true + dev: true + /pretty-format@29.7.0: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -2723,6 +3218,11 @@ packages: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} dev: true + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + /resolve-from@5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} @@ -2750,6 +3250,14 @@ packages: engines: {iojs: '>=1.0.0', node: '>=0.10.0'} dev: true + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + /rollup@4.17.2: resolution: {integrity: sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -3057,6 +3565,11 @@ packages: min-indent: 1.0.1 dev: true + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + /strip-literal@1.3.0: resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} dependencies: @@ -3096,11 +3609,23 @@ packages: engines: {node: '>= 0.4'} dev: true + /synckit@0.9.1: + resolution: {integrity: sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==} + engines: {node: ^14.18.0 || >=16.0.0} + dependencies: + '@pkgr/core': 0.1.1 + tslib: 2.6.2 + dev: true + /term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} dev: true + /text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + /thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -3158,6 +3683,15 @@ packages: engines: {node: '>=8'} dev: true + /ts-api-utils@1.3.0(typescript@5.3.3): + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 5.3.3 + dev: true + /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} dev: true @@ -3250,6 +3784,13 @@ packages: yargs: 17.7.2 dev: true + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + /type-detect@4.0.8: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} @@ -3260,6 +3801,11 @@ packages: engines: {node: '>=10'} dev: true + /type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + /type-fest@0.6.0: resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} engines: {node: '>=8'} @@ -3347,6 +3893,12 @@ packages: engines: {node: '>= 10.0.0'} dev: true + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.1 + dev: true + /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true @@ -3551,6 +4103,11 @@ packages: stackback: 0.0.2 dev: true + /word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + dev: true + /wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -3578,6 +4135,10 @@ packages: strip-ansi: 7.1.0 dev: true + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + /y18n@4.0.3: resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} dev: true From fba0f3c83a686ade446875602208e3826c2d6edc Mon Sep 17 00:00:00 2001 From: johngrantuk Date: Wed, 24 Jul 2024 10:51:21 +0100 Subject: [PATCH 2/5] chore: Apply formatting. --- typescript/src/buffer/index.ts | 2 +- typescript/src/stable/stablePool.ts | 25 +++++++++++++++--------- typescript/src/vault/types.ts | 6 +++--- typescript/src/vault/vault.ts | 2 -- typescript/src/weighted/weightedPool.ts | 26 ++++++++++++++----------- 5 files changed, 35 insertions(+), 26 deletions(-) diff --git a/typescript/src/buffer/index.ts b/typescript/src/buffer/index.ts index ffb8830..610eda5 100644 --- a/typescript/src/buffer/index.ts +++ b/typescript/src/buffer/index.ts @@ -1,2 +1,2 @@ export * from './data'; -export * from './erc4626BufferWrapOrUnwrap'; \ No newline at end of file +export * from './erc4626BufferWrapOrUnwrap'; diff --git a/typescript/src/stable/stablePool.ts b/typescript/src/stable/stablePool.ts index 8b292bd..c2a0b18 100644 --- a/typescript/src/stable/stablePool.ts +++ b/typescript/src/stable/stablePool.ts @@ -15,9 +15,7 @@ import { export class Stable implements PoolBase { public amp: bigint; - constructor(poolState: { - amp: bigint; - }) { + constructor(poolState: { amp: bigint }) { this.amp = poolState.amp; } @@ -28,14 +26,23 @@ export class Stable implements PoolBase { indexIn, indexOut, tokenRates, - scalingFactors + scalingFactors, } = maxSwapParams; if (swapKind === SwapKind.GivenIn) - return MathSol.divDownFixed(MathSol.mulDownFixed( - balancesLiveScaled18[indexOut], - MathSol.divDownFixed(tokenRates[indexOut], tokenRates[indexIn]), - ), scalingFactors[indexIn]); - return MathSol.divDownFixed(balancesLiveScaled18[indexOut], scalingFactors[indexOut]); + return MathSol.divDownFixed( + MathSol.mulDownFixed( + balancesLiveScaled18[indexOut], + MathSol.divDownFixed( + tokenRates[indexOut], + tokenRates[indexIn], + ), + ), + scalingFactors[indexIn], + ); + return MathSol.divDownFixed( + balancesLiveScaled18[indexOut], + scalingFactors[indexOut], + ); } onSwap(swapParams: SwapParams): bigint { diff --git a/typescript/src/vault/types.ts b/typescript/src/vault/types.ts index c7b37c9..6da3270 100644 --- a/typescript/src/vault/types.ts +++ b/typescript/src/vault/types.ts @@ -1,6 +1,6 @@ -import { BufferState } from "../buffer"; -import { StableState } from "../stable"; -import { WeightedState } from "../weighted"; +import { BufferState } from '../buffer'; +import { StableState } from '../stable'; +import { WeightedState } from '../weighted'; export type PoolState = WeightedState | StableState | BufferState; diff --git a/typescript/src/vault/vault.ts b/typescript/src/vault/vault.ts index 84f6dfd..b9c6af5 100644 --- a/typescript/src/vault/vault.ts +++ b/typescript/src/vault/vault.ts @@ -22,8 +22,6 @@ import { SwapParams, } from './types'; - - type PoolClassConstructor = new (..._args: any[]) => PoolBase; type PoolClasses = Readonly>; diff --git a/typescript/src/weighted/weightedPool.ts b/typescript/src/weighted/weightedPool.ts index f2761d1..a622d5f 100644 --- a/typescript/src/weighted/weightedPool.ts +++ b/typescript/src/weighted/weightedPool.ts @@ -17,22 +17,26 @@ import { export class Weighted implements PoolBase { public normalizedWeights: bigint[]; - constructor(poolState: { - weights: bigint[]; - }) { + constructor(poolState: { weights: bigint[] }) { this.normalizedWeights = poolState.weights; } getMaxSwapAmount(swapParams: MaxSwapParams): bigint { if (swapParams.swapKind === SwapKind.GivenIn) - return MathSol.divDownFixed(MathSol.mulDownFixed( - swapParams.balancesLiveScaled18[swapParams.indexIn], - _MAX_IN_RATIO, - ), swapParams.scalingFactors[swapParams.indexIn]); - return MathSol.divDownFixed(MathSol.mulDownFixed( - swapParams.balancesLiveScaled18[swapParams.indexOut], - _MAX_OUT_RATIO, - ), swapParams.scalingFactors[swapParams.indexOut]); + return MathSol.divDownFixed( + MathSol.mulDownFixed( + swapParams.balancesLiveScaled18[swapParams.indexIn], + _MAX_IN_RATIO, + ), + swapParams.scalingFactors[swapParams.indexIn], + ); + return MathSol.divDownFixed( + MathSol.mulDownFixed( + swapParams.balancesLiveScaled18[swapParams.indexOut], + _MAX_OUT_RATIO, + ), + swapParams.scalingFactors[swapParams.indexOut], + ); } onSwap(swapParams: SwapParams): bigint { From 895ba88715a74e38252214e9a393851a439bceab Mon Sep 17 00:00:00 2001 From: johngrantuk Date: Wed, 24 Jul 2024 11:18:57 +0100 Subject: [PATCH 3/5] chore: Temp fix for lint issue. --- typescript/src/vault/vault.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/typescript/src/vault/vault.ts b/typescript/src/vault/vault.ts index b9c6af5..99ea26d 100644 --- a/typescript/src/vault/vault.ts +++ b/typescript/src/vault/vault.ts @@ -22,6 +22,7 @@ import { SwapParams, } from './types'; +// eslint-disable-next-line @typescript-eslint/no-explicit-any type PoolClassConstructor = new (..._args: any[]) => PoolBase; type PoolClasses = Readonly>; From 6aa276de44dd693536221cdf425f672fa7e0db82 Mon Sep 17 00:00:00 2001 From: johngrantuk Date: Wed, 24 Jul 2024 11:39:38 +0100 Subject: [PATCH 4/5] chore: Update testData to use same lint/prettier setup. --- testData/.eslintignore | 2 ++ testData/.eslintrc.cjs | 6 ++++++ testData/.prettierrc | 7 +++++++ testData/bun.lockb | Bin 9338 -> 65635 bytes testData/package.json | 14 ++++++++++++-- testData/tsconfig.json | 3 --- typescript/.eslintrc.js | 2 -- 7 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 testData/.eslintignore create mode 100644 testData/.eslintrc.cjs create mode 100644 testData/.prettierrc diff --git a/testData/.eslintignore b/testData/.eslintignore new file mode 100644 index 0000000..f06235c --- /dev/null +++ b/testData/.eslintignore @@ -0,0 +1,2 @@ +node_modules +dist diff --git a/testData/.eslintrc.cjs b/testData/.eslintrc.cjs new file mode 100644 index 0000000..cdc7d19 --- /dev/null +++ b/testData/.eslintrc.cjs @@ -0,0 +1,6 @@ +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint', 'prettier'], + extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'], +}; diff --git a/testData/.prettierrc b/testData/.prettierrc new file mode 100644 index 0000000..c3fc280 --- /dev/null +++ b/testData/.prettierrc @@ -0,0 +1,7 @@ +{ + "printWidth": 80, + "tabWidth": 4, + "singleQuote": true, + "bracketSpacing": true, + "semi": true +} diff --git a/testData/bun.lockb b/testData/bun.lockb index 2cc56a025ea681e47080282b20fabc3746d48a81..f3d097c2fcc3abbcb3560511d00b2f8528a9ff2b 100755 GIT binary patch literal 65635 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 WoHM}_cVuY&<$KulTMRx*9sComA~}Zu diff --git a/testData/package.json b/testData/package.json index 402ff0e..b864a0b 100644 --- a/testData/package.json +++ b/testData/package.json @@ -3,7 +3,14 @@ "module": "index.ts", "type": "module", "devDependencies": { - "bun-types": "latest" + "@types/bun": "^1.1.6", + "@typescript-eslint/eslint-plugin": "^7.17.0", + "@typescript-eslint/parser": "^7.17.0", + "bun-types": "latest", + "eslint": "^8.56.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.2.1", + "prettier": "^3.3.3" }, "peerDependencies": { "typescript": "^5.0.0" @@ -14,6 +21,9 @@ }, "scripts": { "generate": "bun index.ts false", - "generate:overwrite": "bun index.ts true" + "generate:overwrite": "bun index.ts true", + "format": "prettier --config .prettierrc 'src/**/*.ts' --write", + "lint": "eslint ./src --ext .ts", + "lint:fix": "eslint ./src --ext .ts --fix" } } \ No newline at end of file diff --git a/testData/tsconfig.json b/testData/tsconfig.json index 65b2991..6728972 100644 --- a/testData/tsconfig.json +++ b/testData/tsconfig.json @@ -15,9 +15,6 @@ "allowSyntheticDefaultImports": true, "forceConsistentCasingInFileNames": true, "allowJs": true, - "types": [ - "bun-types" // add Bun global - ] }, "files": [ "../typescript/src/weighted/data.ts", diff --git a/typescript/.eslintrc.js b/typescript/.eslintrc.js index 2e84111..cdc7d19 100644 --- a/typescript/.eslintrc.js +++ b/typescript/.eslintrc.js @@ -3,6 +3,4 @@ module.exports = { parser: '@typescript-eslint/parser', plugins: ['@typescript-eslint', 'prettier'], extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'], - rules: { - }, }; From 9945c30a89adbcc5fad96bd007fd79b60fc1e5c8 Mon Sep 17 00:00:00 2001 From: johngrantuk Date: Wed, 24 Jul 2024 11:39:57 +0100 Subject: [PATCH 5/5] chore: Apply formatting to testData. --- testData/src/generatePoolTestData.ts | 111 +++++++------ testData/src/getAdds.ts | 184 ++++++++++----------- testData/src/getPool.ts | 54 +++---- testData/src/getRemoves.ts | 231 ++++++++++++++------------- testData/src/getSwaps.ts | 146 +++++++++-------- testData/src/stablePool.ts | 212 ++++++++++++------------ testData/src/types.ts | 36 ++--- testData/src/weightedPool.ts | 214 ++++++++++++------------- 8 files changed, 602 insertions(+), 586 deletions(-) diff --git a/testData/src/generatePoolTestData.ts b/testData/src/generatePoolTestData.ts index d0f857d..ba758b2 100644 --- a/testData/src/generatePoolTestData.ts +++ b/testData/src/generatePoolTestData.ts @@ -1,57 +1,68 @@ -import type { TestInput, TestOutput } from "./types"; -import { getSwaps } from "./getSwaps"; -import { getPool } from "./getPool"; -import { getAddLiquiditys } from "./getAdds"; -import { getRemoveLiquiditys } from "./getRemoves"; +import type { TestInput, TestOutput } from './types'; +import { getSwaps } from './getSwaps'; +import { getPool } from './getPool'; +import { getAddLiquiditys } from './getAdds'; +import { getRemoveLiquiditys } from './getRemoves'; export async function generatePoolTestData( - input: TestInput, - overwrite = false, + input: TestInput, + overwrite = false, ) { - const path = `./testData/${input.chainId}-${input.blockNumber}-${input.testName}.json`; - if (!overwrite) { - const file = Bun.file(path); - if (await file.exists()) { - console.log("File already exists and overwrite set to false.", path); - return; - } - } - console.log("Generating test data with input:\n", input); - const testData = await fetchTestData(input); - console.log("Saving test data to: ", path); - await Bun.write(path, JSON.stringify(testData, null, 4)); - console.log("Complete"); + const path = `./testData/${input.chainId}-${input.blockNumber}-${input.testName}.json`; + if (!overwrite) { + const file = Bun.file(path); + if (await file.exists()) { + console.log( + 'File already exists and overwrite set to false.', + path, + ); + return; + } + } + console.log('Generating test data with input:\n', input); + const testData = await fetchTestData(input); + console.log('Saving test data to: ', path); + await Bun.write(path, JSON.stringify(testData, null, 4)); + console.log('Complete'); } async function fetchTestData(input: TestInput): Promise { - const { rpcUrl, chainId, poolAddress, poolType, blockNumber, adds, swaps, removes } = - input; - const pool = await getPool( - rpcUrl, - chainId, - blockNumber, - poolType, - poolAddress, - ); - const swapResults = await getSwaps(swaps, rpcUrl, chainId, poolAddress); - const addResults = await getAddLiquiditys( - adds, - rpcUrl, - chainId, - poolAddress, - poolType, - ); - const removeResults = await getRemoveLiquiditys( - removes, - rpcUrl, - chainId, - poolAddress, - poolType - ) - return { - swaps: swapResults, - adds: addResults, - removes: removeResults, - pool, - }; + const { + rpcUrl, + chainId, + poolAddress, + poolType, + blockNumber, + adds, + swaps, + removes, + } = input; + const pool = await getPool( + rpcUrl, + chainId, + blockNumber, + poolType, + poolAddress, + ); + const swapResults = await getSwaps(swaps, rpcUrl, chainId, poolAddress); + const addResults = await getAddLiquiditys( + adds, + rpcUrl, + chainId, + poolAddress, + poolType, + ); + const removeResults = await getRemoveLiquiditys( + removes, + rpcUrl, + chainId, + poolAddress, + poolType, + ); + return { + swaps: swapResults, + adds: addResults, + removes: removeResults, + pool, + }; } diff --git a/testData/src/getAdds.ts b/testData/src/getAdds.ts index fcb6838..84168d3 100644 --- a/testData/src/getAdds.ts +++ b/testData/src/getAdds.ts @@ -1,116 +1,116 @@ import { - AddLiquidityKind, - type AddLiquidityInput, - AddLiquidity, - OnChainProvider, - type AddLiquidityQueryOutput, -} from "@balancer/sdk"; -import type { Address } from "viem"; + AddLiquidityKind, + type AddLiquidityInput, + AddLiquidity, + OnChainProvider, + type AddLiquidityQueryOutput, +} from '@balancer/sdk'; +import type { Address } from 'viem'; type AddTestInputProportional = { - kind: AddLiquidityKind.Proportional; - inputAmountsRaw: bigint[]; - tokens: Address[]; - decimals: number[]; + kind: AddLiquidityKind.Proportional; + inputAmountsRaw: bigint[]; + tokens: Address[]; + decimals: number[]; }; type AddTestInputSingleToken = { - kind: AddLiquidityKind.SingleToken; - bptOutRaw: bigint; - tokenIn: Address; - decimals: number; + kind: AddLiquidityKind.SingleToken; + bptOutRaw: bigint; + tokenIn: Address; + decimals: number; }; export type AddTestInput = AddTestInputProportional | AddTestInputSingleToken; export type AddLiquidityResult = { - kind: AddLiquidityKind; - inputAmountsRaw: string[]; - bptOutRaw: string; + kind: AddLiquidityKind; + inputAmountsRaw: string[]; + bptOutRaw: string; }; function getInput( - addTestInput: AddTestInput, - chainId: number, - rpcUrl: string, + addTestInput: AddTestInput, + chainId: number, + rpcUrl: string, ): AddLiquidityInput { - const { kind } = addTestInput; - if (kind === AddLiquidityKind.Proportional) { - const amounts = addTestInput.inputAmountsRaw.map((a, i) => ({ - rawAmount: a, - decimals: addTestInput.decimals[i], - address: addTestInput.tokens[i], - })); - const addLiquidityInput: AddLiquidityInput = { - amountsIn: amounts, - chainId, - rpcUrl, - kind: AddLiquidityKind.Unbalanced, - }; - return addLiquidityInput; - // biome-ignore lint/style/noUselessElse: - } else if (kind === AddLiquidityKind.SingleToken) { - const bptAmount = { - rawAmount: addTestInput.bptOutRaw, - decimals: addTestInput.decimals, - address: addTestInput.tokenIn, - }; - const addLiquidityInput: AddLiquidityInput = { - bptOut: bptAmount, - tokenIn: addTestInput.tokenIn, - chainId, - rpcUrl, - kind: AddLiquidityKind.SingleToken, - }; - return addLiquidityInput; - // biome-ignore lint/style/noUselessElse: - } else throw new Error("No support for Custom AddLiquidity kinds"); + const { kind } = addTestInput; + if (kind === AddLiquidityKind.Proportional) { + const amounts = addTestInput.inputAmountsRaw.map((a, i) => ({ + rawAmount: a, + decimals: addTestInput.decimals[i], + address: addTestInput.tokens[i], + })); + const addLiquidityInput: AddLiquidityInput = { + amountsIn: amounts, + chainId, + rpcUrl, + kind: AddLiquidityKind.Unbalanced, + }; + return addLiquidityInput; + // biome-ignore lint/style/noUselessElse: + } else if (kind === AddLiquidityKind.SingleToken) { + const bptAmount = { + rawAmount: addTestInput.bptOutRaw, + decimals: addTestInput.decimals, + address: addTestInput.tokenIn, + }; + const addLiquidityInput: AddLiquidityInput = { + bptOut: bptAmount, + tokenIn: addTestInput.tokenIn, + chainId, + rpcUrl, + kind: AddLiquidityKind.SingleToken, + }; + return addLiquidityInput; + // biome-ignore lint/style/noUselessElse: + } else throw new Error('No support for Custom AddLiquidity kinds'); } async function queryAddLiquidity( - rpcUrl: string, - chainId: number, - poolAddress: Address, - poolType: string, - addTestInput: AddTestInput, + rpcUrl: string, + chainId: number, + poolAddress: Address, + poolType: string, + addTestInput: AddTestInput, ): Promise { - const addLiquidityInput = getInput(addTestInput, chainId, rpcUrl); - // Onchain provider is used to fetch pool state - const onchainProvider = new OnChainProvider(rpcUrl, chainId); - const poolState = await onchainProvider.pools.fetchPoolState( - poolAddress, - poolType, - ); - // Simulate addLiquidity to get the amount of BPT out - const addLiquidity = new AddLiquidity(); - return await addLiquidity.query(addLiquidityInput, poolState); + const addLiquidityInput = getInput(addTestInput, chainId, rpcUrl); + // Onchain provider is used to fetch pool state + const onchainProvider = new OnChainProvider(rpcUrl, chainId); + const poolState = await onchainProvider.pools.fetchPoolState( + poolAddress, + poolType, + ); + // Simulate addLiquidity to get the amount of BPT out + const addLiquidity = new AddLiquidity(); + return await addLiquidity.query(addLiquidityInput, poolState); } export async function getAddLiquiditys( - addTestInputs: AddTestInput[], - rpcUrl: string, - chainId: number, - poolAddress: Address, - poolType: string, + addTestInputs: AddTestInput[], + rpcUrl: string, + chainId: number, + poolAddress: Address, + poolType: string, ): Promise { - if (!addTestInputs) return undefined; - const results: AddLiquidityResult[] = []; - console.log("Querying adds..."); - for (const addTestInput of addTestInputs) { - // TODO - put this in a multicall? - const result = await queryAddLiquidity( - rpcUrl, - chainId, - poolAddress, - poolType, - addTestInput, - ); - results.push({ - kind: addTestInput.kind, - inputAmountsRaw: result.amountsIn.map((a) => a.amount.toString()), - bptOutRaw: result.bptOut.amount.toString(), - }); - } - console.log("Done"); - return results; + if (!addTestInputs) return undefined; + const results: AddLiquidityResult[] = []; + console.log('Querying adds...'); + for (const addTestInput of addTestInputs) { + // TODO - put this in a multicall? + const result = await queryAddLiquidity( + rpcUrl, + chainId, + poolAddress, + poolType, + addTestInput, + ); + results.push({ + kind: addTestInput.kind, + inputAmountsRaw: result.amountsIn.map((a) => a.amount.toString()), + bptOutRaw: result.bptOut.amount.toString(), + }); + } + console.log('Done'); + return results; } diff --git a/testData/src/getPool.ts b/testData/src/getPool.ts index e65ee28..a5f45e0 100644 --- a/testData/src/getPool.ts +++ b/testData/src/getPool.ts @@ -1,33 +1,33 @@ -import type { Address } from "viem"; -import { WeightedPool } from "./weightedPool"; -import { StablePool } from "./stablePool"; -import type { PoolBase } from "./types"; +import type { Address } from 'viem'; +import { WeightedPool } from './weightedPool'; +import { StablePool } from './stablePool'; +import type { PoolBase } from './types'; export async function getPool( - rpcUrl: string, - chainId: number, - blockNumber: number, - poolType: string, - poolAddress: Address, + rpcUrl: string, + chainId: number, + blockNumber: number, + poolType: string, + poolAddress: Address, ): Promise { - // Find onchain data fetching via pool type - const poolData = { - Weighted: new WeightedPool(rpcUrl, chainId), - Stable: new StablePool(rpcUrl, chainId), - }; - if (!poolData[poolType]) throw new Error("getPool: Unsupported pool type"); + // Find onchain data fetching via pool type + const poolData = { + Weighted: new WeightedPool(rpcUrl, chainId), + Stable: new StablePool(rpcUrl, chainId), + }; + if (!poolData[poolType]) throw new Error('getPool: Unsupported pool type'); - console.log("Fetching pool data..."); - const immutable = await poolData[poolType].fetchImmutableData(poolAddress); - const mutable = await poolData[poolType].fetchMutableData(poolAddress); - console.log("Done"); + console.log('Fetching pool data...'); + const immutable = await poolData[poolType].fetchImmutableData(poolAddress); + const mutable = await poolData[poolType].fetchMutableData(poolAddress); + console.log('Done'); - return { - chainId, - blockNumber, - poolType, - poolAddress, - ...immutable, - ...mutable, - }; + return { + chainId, + blockNumber, + poolType, + poolAddress, + ...immutable, + ...mutable, + }; } diff --git a/testData/src/getRemoves.ts b/testData/src/getRemoves.ts index ac7527f..cf6bf75 100644 --- a/testData/src/getRemoves.ts +++ b/testData/src/getRemoves.ts @@ -1,141 +1,144 @@ import { - RemoveLiquidityKind, - RemoveLiquidity, - OnChainProvider, - type RemoveLiquidityQueryOutput, - type RemoveLiquidityInput, - type RemoveLiquidityProportionalInput, - type RemoveLiquiditySingleTokenExactInInput, - type RemoveLiquiditySingleTokenExactOutInput, -} from "@balancer/sdk"; -import type { Address } from "viem"; + RemoveLiquidityKind, + RemoveLiquidity, + OnChainProvider, + type RemoveLiquidityQueryOutput, + type RemoveLiquidityInput, + type RemoveLiquidityProportionalInput, + type RemoveLiquiditySingleTokenExactInInput, + type RemoveLiquiditySingleTokenExactOutInput, +} from '@balancer/sdk'; +import type { Address } from 'viem'; type RemoveTestInputProportional = { - bpt: Address; - kind: RemoveLiquidityKind.Proportional; - bptInRaw: bigint; + bpt: Address; + kind: RemoveLiquidityKind.Proportional; + bptInRaw: bigint; }; type RemoveTestInputSingleTokenExactIn = { - bpt: Address; - token: Address; - kind: RemoveLiquidityKind.SingleTokenExactIn; - bptInRaw: bigint; + bpt: Address; + token: Address; + kind: RemoveLiquidityKind.SingleTokenExactIn; + bptInRaw: bigint; }; type RemoveTestInputSingleTokenExactOut = { - token: Address; - kind: RemoveLiquidityKind.SingleTokenExactOut; - amountOutRaw: bigint; - decimals: number + token: Address; + kind: RemoveLiquidityKind.SingleTokenExactOut; + amountOutRaw: bigint; + decimals: number; }; -export type RemoveTestInput = RemoveTestInputProportional | RemoveTestInputSingleTokenExactIn | RemoveTestInputSingleTokenExactOut; +export type RemoveTestInput = + | RemoveTestInputProportional + | RemoveTestInputSingleTokenExactIn + | RemoveTestInputSingleTokenExactOut; export type RemoveLiquidityResult = { - kind: RemoveLiquidityKind; - amountsOutRaw: string[]; - bptInRaw: string; + kind: RemoveLiquidityKind; + amountsOutRaw: string[]; + bptInRaw: string; }; function getInput( - removeTestInput: RemoveTestInput, - chainId: number, - rpcUrl: string, + removeTestInput: RemoveTestInput, + chainId: number, + rpcUrl: string, ): RemoveLiquidityInput { - const { kind } = removeTestInput; + const { kind } = removeTestInput; - if (kind === RemoveLiquidityKind.Proportional) { - const bptIn = { - rawAmount: removeTestInput.bptInRaw, - decimals: 18, - address: removeTestInput.bpt, - }; - const removeLiquidityInput: RemoveLiquidityProportionalInput = { - chainId, - rpcUrl, - bptIn, - kind: RemoveLiquidityKind.Proportional, - }; - return removeLiquidityInput; - // biome-ignore lint/style/noUselessElse: - } else if (kind === RemoveLiquidityKind.SingleTokenExactIn) { - const bptIn = { - rawAmount: removeTestInput.bptInRaw, - decimals: 18, - address: removeTestInput.bpt, - }; - const removeLiquidityInput: RemoveLiquiditySingleTokenExactInInput = { - chainId, - rpcUrl, - tokenOut: removeTestInput.token, - kind: RemoveLiquidityKind.SingleTokenExactIn, - bptIn, - }; - return removeLiquidityInput; - // biome-ignore lint/style/noUselessElse: - } else if (kind === RemoveLiquidityKind.SingleTokenExactOut) { - const amountOut = { - rawAmount: removeTestInput.amountOutRaw, - decimals: removeTestInput.decimals, - address: removeTestInput.token, - }; - const removeLiquidityInput: RemoveLiquiditySingleTokenExactOutInput = { - chainId, - rpcUrl, - kind: RemoveLiquidityKind.SingleTokenExactOut, - amountOut, - }; - return removeLiquidityInput; - } - // biome-ignore lint/style/noUselessElse: - else throw new Error("No support for Custom AddLiquidity kinds"); + if (kind === RemoveLiquidityKind.Proportional) { + const bptIn = { + rawAmount: removeTestInput.bptInRaw, + decimals: 18, + address: removeTestInput.bpt, + }; + const removeLiquidityInput: RemoveLiquidityProportionalInput = { + chainId, + rpcUrl, + bptIn, + kind: RemoveLiquidityKind.Proportional, + }; + return removeLiquidityInput; + // biome-ignore lint/style/noUselessElse: + } else if (kind === RemoveLiquidityKind.SingleTokenExactIn) { + const bptIn = { + rawAmount: removeTestInput.bptInRaw, + decimals: 18, + address: removeTestInput.bpt, + }; + const removeLiquidityInput: RemoveLiquiditySingleTokenExactInInput = { + chainId, + rpcUrl, + tokenOut: removeTestInput.token, + kind: RemoveLiquidityKind.SingleTokenExactIn, + bptIn, + }; + return removeLiquidityInput; + // biome-ignore lint/style/noUselessElse: + } else if (kind === RemoveLiquidityKind.SingleTokenExactOut) { + const amountOut = { + rawAmount: removeTestInput.amountOutRaw, + decimals: removeTestInput.decimals, + address: removeTestInput.token, + }; + const removeLiquidityInput: RemoveLiquiditySingleTokenExactOutInput = { + chainId, + rpcUrl, + kind: RemoveLiquidityKind.SingleTokenExactOut, + amountOut, + }; + return removeLiquidityInput; + } + // biome-ignore lint/style/noUselessElse: + else throw new Error('No support for Custom AddLiquidity kinds'); } async function queryRemoveLiquidity( - rpcUrl: string, - chainId: number, - poolAddress: Address, - poolType: string, - removeTestInput: RemoveTestInput, + rpcUrl: string, + chainId: number, + poolAddress: Address, + poolType: string, + removeTestInput: RemoveTestInput, ): Promise { - const removeLiquidityInput = getInput(removeTestInput, chainId, rpcUrl); - // Onchain provider is used to fetch pool state - const onchainProvider = new OnChainProvider(rpcUrl, chainId); - const poolState = await onchainProvider.pools.fetchPoolState( - poolAddress, - poolType, - ); - // Simulate addLiquidity to get the amount of BPT out - const removeLiquidity = new RemoveLiquidity(); - return await removeLiquidity.query(removeLiquidityInput, poolState); + const removeLiquidityInput = getInput(removeTestInput, chainId, rpcUrl); + // Onchain provider is used to fetch pool state + const onchainProvider = new OnChainProvider(rpcUrl, chainId); + const poolState = await onchainProvider.pools.fetchPoolState( + poolAddress, + poolType, + ); + // Simulate addLiquidity to get the amount of BPT out + const removeLiquidity = new RemoveLiquidity(); + return await removeLiquidity.query(removeLiquidityInput, poolState); } export async function getRemoveLiquiditys( - removeTestInputs: RemoveTestInput[], - rpcUrl: string, - chainId: number, - poolAddress: Address, - poolType: string, + removeTestInputs: RemoveTestInput[], + rpcUrl: string, + chainId: number, + poolAddress: Address, + poolType: string, ): Promise { - if (!removeTestInputs) return undefined; - const results: RemoveLiquidityResult[] = []; - console.log("Querying removes..."); - for (const removeTestInput of removeTestInputs) { - // TODO - put this in a multicall? - const result = await queryRemoveLiquidity( - rpcUrl, - chainId, - poolAddress, - poolType, - removeTestInput, - ); - results.push({ - kind: removeTestInput.kind, - amountsOutRaw: result.amountsOut.map((a) => a.amount.toString()), - bptInRaw: result.bptIn.amount.toString(), - }); - } - console.log("Done"); - return results; + if (!removeTestInputs) return undefined; + const results: RemoveLiquidityResult[] = []; + console.log('Querying removes...'); + for (const removeTestInput of removeTestInputs) { + // TODO - put this in a multicall? + const result = await queryRemoveLiquidity( + rpcUrl, + chainId, + poolAddress, + poolType, + removeTestInput, + ); + results.push({ + kind: removeTestInput.kind, + amountsOutRaw: result.amountsOut.map((a) => a.amount.toString()), + bptInRaw: result.bptIn.amount.toString(), + }); + } + console.log('Done'); + return results; } diff --git a/testData/src/getSwaps.ts b/testData/src/getSwaps.ts index 5c92829..218cafc 100644 --- a/testData/src/getSwaps.ts +++ b/testData/src/getSwaps.ts @@ -1,84 +1,90 @@ -import type { Address } from "viem"; +import type { Address } from 'viem'; import { - SwapKind, - Swap, - type SwapInput as SdkSwapInput, - type ExactInQueryOutput, - type ExactOutQueryOutput, -} from "@balancer/sdk"; + SwapKind, + Swap, + type SwapInput as SdkSwapInput, + type ExactInQueryOutput, + type ExactOutQueryOutput, +} from '@balancer/sdk'; export type SwapInput = { - swapKind: SwapKind; - amountRaw: bigint; - tokenIn: Address; - tokenOut: Address; + swapKind: SwapKind; + amountRaw: bigint; + tokenIn: Address; + tokenOut: Address; }; -export type SwapResult = Omit & { - amountRaw: string; - outputRaw: string; +export type SwapResult = Omit & { + amountRaw: string; + outputRaw: string; }; async function querySwap( - chainId: number, - poolAddress: Address, - rpcUrl: string, - swap: SwapInput, + chainId: number, + poolAddress: Address, + rpcUrl: string, + swap: SwapInput, ): Promise { - const swapInput: SdkSwapInput = { - chainId: chainId, - swapKind: swap.swapKind, - paths: [ - { - pools: [poolAddress], - tokens: [ - { - address: swap.tokenIn, - decimals: 18, - }, // tokenIn - { - address: swap.tokenOut, - decimals: 18, - }, // tokenOut - ], - vaultVersion: 3 as const, - inputAmountRaw: - swap.swapKind === SwapKind.GivenIn ? BigInt(swap.amountRaw) : 0n, - outputAmountRaw: - swap.swapKind === SwapKind.GivenOut ? BigInt(swap.amountRaw) : 0n, - }, - ], - }; - const sdkSwap = new Swap(swapInput); - let result = 0n; - if (swap.swapKind === SwapKind.GivenIn) { - const queryResult = (await sdkSwap.query(rpcUrl)) as ExactInQueryOutput; - result = queryResult.expectedAmountOut.amount; - } else { - const queryResult = (await sdkSwap.query(rpcUrl)) as ExactOutQueryOutput; - result = queryResult.expectedAmountIn.amount; - } - return result; + const swapInput: SdkSwapInput = { + chainId: chainId, + swapKind: swap.swapKind, + paths: [ + { + pools: [poolAddress], + tokens: [ + { + address: swap.tokenIn, + decimals: 18, + }, // tokenIn + { + address: swap.tokenOut, + decimals: 18, + }, // tokenOut + ], + vaultVersion: 3 as const, + inputAmountRaw: + swap.swapKind === SwapKind.GivenIn + ? BigInt(swap.amountRaw) + : 0n, + outputAmountRaw: + swap.swapKind === SwapKind.GivenOut + ? BigInt(swap.amountRaw) + : 0n, + }, + ], + }; + const sdkSwap = new Swap(swapInput); + let result = 0n; + if (swap.swapKind === SwapKind.GivenIn) { + const queryResult = (await sdkSwap.query(rpcUrl)) as ExactInQueryOutput; + result = queryResult.expectedAmountOut.amount; + } else { + const queryResult = (await sdkSwap.query( + rpcUrl, + )) as ExactOutQueryOutput; + result = queryResult.expectedAmountIn.amount; + } + return result; } export async function getSwaps( - swapTestInputs: SwapInput[], - rpcUrl: string, - chainId: number, - poolAddress: Address, + swapTestInputs: SwapInput[], + rpcUrl: string, + chainId: number, + poolAddress: Address, ): Promise { - if (!swapTestInputs) return undefined; - const results: SwapResult[] = []; - console.log("Querying swaps..."); - for (const swap of swapTestInputs) { - // get swap. TODO - put this in a multicall? - const result = await querySwap(chainId, poolAddress, rpcUrl, swap); - results.push({ - ...swap, - amountRaw: swap.amountRaw.toString(), - outputRaw: result.toString(), - }); - } - console.log("Done"); - return results; + if (!swapTestInputs) return undefined; + const results: SwapResult[] = []; + console.log('Querying swaps...'); + for (const swap of swapTestInputs) { + // get swap. TODO - put this in a multicall? + const result = await querySwap(chainId, poolAddress, rpcUrl, swap); + results.push({ + ...swap, + amountRaw: swap.amountRaw.toString(), + outputRaw: result.toString(), + }); + } + console.log('Done'); + return results; } diff --git a/testData/src/stablePool.ts b/testData/src/stablePool.ts index 64dcfa0..dcde422 100644 --- a/testData/src/stablePool.ts +++ b/testData/src/stablePool.ts @@ -1,118 +1,118 @@ import { - type PublicClient, - createPublicClient, - http, - type Address, - parseAbi, - type Chain, -} from "viem"; -import { CHAINS, VAULT_V3, vaultExtensionV3Abi } from "@balancer/sdk"; + type PublicClient, + createPublicClient, + http, + type Address, + parseAbi, + type Chain, +} from 'viem'; +import { CHAINS, VAULT_V3, vaultExtensionV3Abi } from '@balancer/sdk'; import type { - StableImmutable, - StableMutable, -} from "../../typescript/src/stable/data"; + StableImmutable, + StableMutable, +} from '../../typescript/src/stable/data'; type TransformBigintToString = { - [K in keyof T]: T[K] extends bigint - ? string - : T[K] extends bigint[] - ? string[] - : T[K]; + [K in keyof T]: T[K] extends bigint + ? string + : T[K] extends bigint[] + ? string[] + : T[K]; }; export class StablePool { - client: PublicClient; - vault: Address; + client: PublicClient; + vault: Address; - constructor( - public rpcUrl: string, - public chainId: number, - ) { - this.client = createPublicClient({ - transport: http(this.rpcUrl), - chain: CHAINS[this.chainId] as Chain, - }); - this.vault = VAULT_V3[this.chainId]; - } + constructor( + public rpcUrl: string, + public chainId: number, + ) { + this.client = createPublicClient({ + transport: http(this.rpcUrl), + chain: CHAINS[this.chainId] as Chain, + }); + this.vault = VAULT_V3[this.chainId]; + } - async fetchImmutableData( - address: Address, - ): Promise> { - const poolTokensCall = { - address: this.vault, - abi: vaultExtensionV3Abi, - functionName: "getPoolTokenInfo", - args: [address], - } as const; - const tokenRatesCall = { - address: this.vault, - abi: vaultExtensionV3Abi, - functionName: "getPoolTokenRates", - args: [address], - } as const; - const multicallResult = await this.client.multicall({ - contracts: [poolTokensCall, tokenRatesCall], - allowFailure: false, - }); - return { - tokens: multicallResult[0][0].map((token) => token), - scalingFactors: multicallResult[1][0].map((sf) => sf.toString()), - }; - } + async fetchImmutableData( + address: Address, + ): Promise> { + const poolTokensCall = { + address: this.vault, + abi: vaultExtensionV3Abi, + functionName: 'getPoolTokenInfo', + args: [address], + } as const; + const tokenRatesCall = { + address: this.vault, + abi: vaultExtensionV3Abi, + functionName: 'getPoolTokenRates', + args: [address], + } as const; + const multicallResult = await this.client.multicall({ + contracts: [poolTokensCall, tokenRatesCall], + allowFailure: false, + }); + return { + tokens: multicallResult[0][0].map((token) => token), + scalingFactors: multicallResult[1][0].map((sf) => sf.toString()), + }; + } - async fetchMutableData( - address: Address, - ): Promise> { - const staticSwapFeeCall = { - address: this.vault, - abi: vaultExtensionV3Abi, - functionName: "getStaticSwapFeePercentage", - args: [address], - } as const; - const totalSupplyCall = { - address: this.vault, - abi: parseAbi([ - "function totalSupply(address token) external view returns (uint256)", - ]), - functionName: "totalSupply", - args: [address], - } as const; - const liveBalancesCall = { - address: this.vault, - abi: vaultExtensionV3Abi, - functionName: "getCurrentLiveBalances", - args: [address], - } as const; - const tokenRatesCall = { - address: this.vault, - abi: vaultExtensionV3Abi, - functionName: "getPoolTokenRates", - args: [address], - } as const; - const amplificationParameterCall = { - address, - abi: parseAbi([ - "function getAmplificationParameter() external view returns (uint256 value, bool isUpdating, uint256 precision)", - ]), - functionName: "getAmplificationParameter", - } as const; + async fetchMutableData( + address: Address, + ): Promise> { + const staticSwapFeeCall = { + address: this.vault, + abi: vaultExtensionV3Abi, + functionName: 'getStaticSwapFeePercentage', + args: [address], + } as const; + const totalSupplyCall = { + address: this.vault, + abi: parseAbi([ + 'function totalSupply(address token) external view returns (uint256)', + ]), + functionName: 'totalSupply', + args: [address], + } as const; + const liveBalancesCall = { + address: this.vault, + abi: vaultExtensionV3Abi, + functionName: 'getCurrentLiveBalances', + args: [address], + } as const; + const tokenRatesCall = { + address: this.vault, + abi: vaultExtensionV3Abi, + functionName: 'getPoolTokenRates', + args: [address], + } as const; + const amplificationParameterCall = { + address, + abi: parseAbi([ + 'function getAmplificationParameter() external view returns (uint256 value, bool isUpdating, uint256 precision)', + ]), + functionName: 'getAmplificationParameter', + } as const; - const multicallResult = await this.client.multicall({ - contracts: [ - staticSwapFeeCall, - totalSupplyCall, - liveBalancesCall, - tokenRatesCall, - amplificationParameterCall, - ], - allowFailure: false, - }); - return { - swapFee: multicallResult[0].toString(), - totalSupply: multicallResult[1].toString(), - balancesLiveScaled18: multicallResult[2].map((b) => b.toString()), - tokenRates: multicallResult[3][1].map((b) => b.toString()), - amp: multicallResult[4][0].toString(), - }; - } + const multicallResult = await this.client.multicall({ + contracts: [ + staticSwapFeeCall, + totalSupplyCall, + liveBalancesCall, + tokenRatesCall, + amplificationParameterCall, + ], + allowFailure: false, + }); + return { + swapFee: multicallResult[0].toString(), + totalSupply: multicallResult[1].toString(), + balancesLiveScaled18: multicallResult[2].map((b) => b.toString()), + tokenRates: multicallResult[3][1].map((b) => b.toString()), + amp: multicallResult[4][0].toString(), + }; + } } diff --git a/testData/src/types.ts b/testData/src/types.ts index 66b55d1..003f3fb 100644 --- a/testData/src/types.ts +++ b/testData/src/types.ts @@ -1,35 +1,35 @@ -import type { Address } from "viem"; -import type { AddLiquidityResult, AddTestInput } from "./getAdds"; -import type { SwapResult, SwapInput } from "./getSwaps"; -import type { RemoveLiquidityResult, RemoveTestInput } from "./getRemoves"; +import type { Address } from 'viem'; +import type { AddLiquidityResult, AddTestInput } from './getAdds'; +import type { SwapResult, SwapInput } from './getSwaps'; +import type { RemoveLiquidityResult, RemoveTestInput } from './getRemoves'; export type PoolBase = { - chainId: number; - blockNumber: number; - poolType: string; - poolAddress: Address; + chainId: number; + blockNumber: number; + poolType: string; + poolAddress: Address; }; // Read from main test config file export type Config = { - poolTests: PoolTestConfig[]; + poolTests: PoolTestConfig[]; }; // Each pool/chain/block has its own set of swap/add/remove tests type PoolTestConfig = PoolBase & { - testName: string; - swaps: SwapInput[]; - adds: AddTestInput[]; - removes: RemoveTestInput[]; + testName: string; + swaps: SwapInput[]; + adds: AddTestInput[]; + removes: RemoveTestInput[]; }; export type TestInput = PoolTestConfig & { - rpcUrl: string; + rpcUrl: string; }; export type TestOutput = { - pool: PoolBase; - swaps: SwapResult[] | undefined; - adds: AddLiquidityResult[] | undefined; - removes: RemoveLiquidityResult[] | undefined; + pool: PoolBase; + swaps: SwapResult[] | undefined; + adds: AddLiquidityResult[] | undefined; + removes: RemoveLiquidityResult[] | undefined; }; diff --git a/testData/src/weightedPool.ts b/testData/src/weightedPool.ts index 9a05d2a..7f52521 100644 --- a/testData/src/weightedPool.ts +++ b/testData/src/weightedPool.ts @@ -1,122 +1,118 @@ import { - type PublicClient, - createPublicClient, - http, - type Address, - parseAbi, - type Chain, -} from "viem"; -import { - CHAINS, - VAULT_V3, - vaultExtensionV3Abi, -} from "@balancer/sdk"; + type PublicClient, + createPublicClient, + http, + type Address, + parseAbi, + type Chain, +} from 'viem'; +import { CHAINS, VAULT_V3, vaultExtensionV3Abi } from '@balancer/sdk'; import type { - WeightedImmutable, - WeightedMutable, -} from "../../typescript/src/weighted/data"; + WeightedImmutable, + WeightedMutable, +} from '../../typescript/src/weighted/data'; type TransformBigintToString = { - [K in keyof T]: T[K] extends bigint - ? string - : T[K] extends bigint[] - ? string[] - : T[K]; + [K in keyof T]: T[K] extends bigint + ? string + : T[K] extends bigint[] + ? string[] + : T[K]; }; export class WeightedPool { - client: PublicClient; - vault: Address; + client: PublicClient; + vault: Address; - constructor( - public rpcUrl: string, - public chainId: number, - ) { - this.client = createPublicClient({ - transport: http(this.rpcUrl), - chain: CHAINS[this.chainId] as Chain, - }); - this.vault = VAULT_V3[this.chainId]; - } + constructor( + public rpcUrl: string, + public chainId: number, + ) { + this.client = createPublicClient({ + transport: http(this.rpcUrl), + chain: CHAINS[this.chainId] as Chain, + }); + this.vault = VAULT_V3[this.chainId]; + } - async fetchImmutableData( - address: Address, - ): Promise> { - const poolTokensCall = { - address: this.vault, - abi: vaultExtensionV3Abi, - functionName: "getPoolTokenInfo", - args: [address], - } as const; - const tokenRatesCall = { - address: this.vault, - abi: vaultExtensionV3Abi, - functionName: "getPoolTokenRates", - args: [address], - } as const; - const tokenWeightsCall = { - address, - abi: parseAbi([ - "function getNormalizedWeights() external view returns (uint256[] memory)", - ]), - functionName: "getNormalizedWeights", - } as const; + async fetchImmutableData( + address: Address, + ): Promise> { + const poolTokensCall = { + address: this.vault, + abi: vaultExtensionV3Abi, + functionName: 'getPoolTokenInfo', + args: [address], + } as const; + const tokenRatesCall = { + address: this.vault, + abi: vaultExtensionV3Abi, + functionName: 'getPoolTokenRates', + args: [address], + } as const; + const tokenWeightsCall = { + address, + abi: parseAbi([ + 'function getNormalizedWeights() external view returns (uint256[] memory)', + ]), + functionName: 'getNormalizedWeights', + } as const; - const multicallResult = await this.client.multicall({ - contracts: [poolTokensCall, tokenRatesCall, tokenWeightsCall], - allowFailure: false, - }); - return { - tokens: multicallResult[0][0].map((token) => token), - scalingFactors: multicallResult[1][0].map((sf) => sf.toString()), - weights: multicallResult[2].map((w) => w.toString()), - }; - } + const multicallResult = await this.client.multicall({ + contracts: [poolTokensCall, tokenRatesCall, tokenWeightsCall], + allowFailure: false, + }); + return { + tokens: multicallResult[0][0].map((token) => token), + scalingFactors: multicallResult[1][0].map((sf) => sf.toString()), + weights: multicallResult[2].map((w) => w.toString()), + }; + } - async fetchMutableData( - address: Address, - ): Promise> { - const staticSwapFeeCall = { - address: this.vault, - abi: vaultExtensionV3Abi, - functionName: "getStaticSwapFeePercentage", - args: [address], - } as const; - const totalSupplyCall = { - address: this.vault, - abi: parseAbi([ - "function totalSupply(address token) external view returns (uint256)", - ]), - functionName: "totalSupply", - args: [address], - } as const; - const liveBalancesCall = { - address: this.vault, - abi: vaultExtensionV3Abi, - functionName: "getCurrentLiveBalances", - args: [address], - } as const; - const tokenRatesCall = { - address: this.vault, - abi: vaultExtensionV3Abi, - functionName: "getPoolTokenRates", - args: [address], - } as const; + async fetchMutableData( + address: Address, + ): Promise> { + const staticSwapFeeCall = { + address: this.vault, + abi: vaultExtensionV3Abi, + functionName: 'getStaticSwapFeePercentage', + args: [address], + } as const; + const totalSupplyCall = { + address: this.vault, + abi: parseAbi([ + 'function totalSupply(address token) external view returns (uint256)', + ]), + functionName: 'totalSupply', + args: [address], + } as const; + const liveBalancesCall = { + address: this.vault, + abi: vaultExtensionV3Abi, + functionName: 'getCurrentLiveBalances', + args: [address], + } as const; + const tokenRatesCall = { + address: this.vault, + abi: vaultExtensionV3Abi, + functionName: 'getPoolTokenRates', + args: [address], + } as const; - const multicallResult = await this.client.multicall({ - contracts: [ - staticSwapFeeCall, - totalSupplyCall, - liveBalancesCall, - tokenRatesCall - ], - allowFailure: false, - }); - return { - swapFee: multicallResult[0].toString(), - totalSupply: multicallResult[1].toString(), - balancesLiveScaled18: multicallResult[2].map((b) => b.toString()), - tokenRates: multicallResult[3][1].map((b) => b.toString()), - }; - } + const multicallResult = await this.client.multicall({ + contracts: [ + staticSwapFeeCall, + totalSupplyCall, + liveBalancesCall, + tokenRatesCall, + ], + allowFailure: false, + }); + return { + swapFee: multicallResult[0].toString(), + totalSupply: multicallResult[1].toString(), + balancesLiveScaled18: multicallResult[2].map((b) => b.toString()), + tokenRates: multicallResult[3][1].map((b) => b.toString()), + }; + } }