diff --git a/.editorconfig b/.editorconfig index 9c34fd3..19ebc50 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,3 +1,7 @@ [*] indent_size = 4 -indent_style = tab \ No newline at end of file +indent_style = tab + +[{*.yml, *.yaml}] +indent_size = 2 +indent_style = space \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..119931b --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,42 @@ +{ + "env": { + "browser": true, + "es2021": true, + "node": true + }, + "extends": [ + // "next/core-web-vitals", + "eslint:recommended", + // "plugin:react/recommended", + "plugin:@typescript-eslint/recommended", + "prettier" + ], + "overrides": [], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": [ + // "react", + "@typescript-eslint", + "simple-import-sort" + ], + "rules": { + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/ban-types": "warn", + "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/no-explicit-any": "off", + "linebreak-style": ["error", "unix"], + "no-empty": "warn", + "no-empty-function": "off", + "no-empty-pattern": "warn", + // "react/react-in-jsx-scope": "off", + "simple-import-sort/imports": [ + "warn", + { + "groups": [["^\\w"], ["^@\\w+"], ["^@/"], ["^\\."]] + } + ] + } +} \ No newline at end of file diff --git a/.npmignore b/.npmignore index 225653b..8edcc6e 100644 --- a/.npmignore +++ b/.npmignore @@ -6,4 +6,5 @@ .prettierrc .editorconfig .npmrc -tsconfig.json \ No newline at end of file +tsconfig.json +.eslintrc.json \ No newline at end of file diff --git a/.prettierrc b/.prettierrc index 56eb3d4..5728c81 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,8 +1,11 @@ { "semi": false, "arrowParens": "avoid", - "trailingComma": "none", + "trailingComma": "all", "jsxSingleQuote": false, - "jsxBracketSameLine": true, - "printWidth": 100 + "printWidth": 100, + "singleAttributePerLine": true, + "bracketSameLine": true, + "useTabs": true, + "tabWidth": 4 } \ No newline at end of file diff --git a/package.json b/package.json index 094da7c..43e187e 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,12 @@ "scripts": { "test": "ts-mocha --timeout 30000 src/__tests__/**/*.spec.ts", "docs:dev": "vuepress dev docs", - "docs:build": "vuepress build docs" + "docs:build": "vuepress build docs", + "lint": "eslint src", + "lint:fix": "eslint src --fix", + "prettier": "prettier src --check", + "prettier:fix": "prettier src --write", + "clean": "tsc --noEmit && eslint src --fix && prettier src --write" }, "dependencies": { "axios": "^0.27.2", @@ -26,10 +31,17 @@ "@types/mocha": "^10.0.1", "@types/node": "^18.11.17", "@types/tough-cookie": "^4.0.2", + "@typescript-eslint/eslint-plugin": "latest", + "@typescript-eslint/parser": "latest", "@vuepress/plugin-search": "^2.0.0-beta.46", + "eslint": "latest", + "eslint-config-prettier": "latest", + "eslint-plugin-simple-import-sort": "latest", "mocha": "^10.2.0", "mocha.parallel": "^0.15.6", + "prettier": "latest", "ts-mocha": "^10.0.0", + "ts-node": "^10.9.1", "typescript": "^4.9.4", "vuepress": "^2.0.0-beta.46" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cb49546..31045f6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,18 +31,39 @@ devDependencies: '@types/tough-cookie': specifier: ^4.0.2 version: 4.0.2 + '@typescript-eslint/eslint-plugin': + specifier: latest + version: 6.2.0(@typescript-eslint/parser@6.2.0)(eslint@8.46.0)(typescript@4.9.4) + '@typescript-eslint/parser': + specifier: latest + version: 6.2.0(eslint@8.46.0)(typescript@4.9.4) '@vuepress/plugin-search': specifier: ^2.0.0-beta.46 version: 2.0.0-beta.46 + eslint: + specifier: latest + version: 8.46.0 + eslint-config-prettier: + specifier: latest + version: 8.9.0(eslint@8.46.0) + eslint-plugin-simple-import-sort: + specifier: latest + version: 10.0.0(eslint@8.46.0) mocha: specifier: ^10.2.0 version: 10.2.0 mocha.parallel: specifier: ^0.15.6 version: 0.15.6(mocha@10.2.0) + prettier: + specifier: latest + version: 3.0.0 ts-mocha: specifier: ^10.0.0 version: 10.0.0(mocha@10.2.0) + ts-node: + specifier: ^10.9.1 + version: 10.9.1(@types/node@18.11.17)(typescript@4.9.4) typescript: specifier: ^4.9.4 version: 4.9.4 @@ -52,6 +73,11 @@ devDependencies: packages: + /@aashutoshrathi/word-wrap@1.2.6: + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + dev: true + /@babel/helper-validator-identifier@7.16.7: resolution: {integrity: sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==} engines: {node: '>=6.9.0'} @@ -73,6 +99,86 @@ packages: to-fast-properties: 2.0.0 dev: true + /@cspotcode/source-map-support@0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + dev: true + + /@eslint-community/eslint-utils@4.4.0(eslint@8.46.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.46.0 + eslint-visitor-keys: 3.4.2 + dev: true + + /@eslint-community/regexpp@4.6.2: + resolution: {integrity: sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@2.1.1: + resolution: {integrity: sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4(supports-color@8.1.1) + espree: 9.6.1 + globals: 13.20.0 + ignore: 5.2.0 + 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.46.0: + resolution: {integrity: sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@humanwhocodes/config-array@0.11.10: + resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 1.2.1 + debug: 4.3.4(supports-color@8.1.1) + 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@1.2.1: + resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + dev: true + + /@jridgewell/resolve-uri@3.1.1: + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + + /@jridgewell/trace-mapping@0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -94,6 +200,22 @@ packages: fastq: 1.13.0 dev: true + /@tsconfig/node10@1.0.9: + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + dev: true + + /@tsconfig/node12@1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: true + + /@tsconfig/node14@1.0.3: + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: true + + /@tsconfig/node16@1.0.4: + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + dev: true + /@types/debug@4.1.7: resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==} dependencies: @@ -110,6 +232,10 @@ packages: resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} dev: true + /@types/json-schema@7.0.12: + resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} + dev: true + /@types/json5@0.0.29: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} requiresBuild: true @@ -143,10 +269,146 @@ packages: resolution: {integrity: sha512-HJSUJmni4BeDHhfzn6nF0sVmd1SMezP7/4F0Lq+aXzmp2xm9O7WXrUtHW/CHlYVtZUbByEvWidHqRtcJXGF2Ng==} dev: true + /@types/semver@7.5.0: + resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} + dev: true + /@types/tough-cookie@4.0.2: resolution: {integrity: sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==} dev: true + /@typescript-eslint/eslint-plugin@6.2.0(@typescript-eslint/parser@6.2.0)(eslint@8.46.0)(typescript@4.9.4): + resolution: {integrity: sha512-rClGrMuyS/3j0ETa1Ui7s6GkLhfZGKZL3ZrChLeAiACBE/tRc1wq8SNZESUuluxhLj9FkUefRs2l6bCIArWBiQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@eslint-community/regexpp': 4.6.2 + '@typescript-eslint/parser': 6.2.0(eslint@8.46.0)(typescript@4.9.4) + '@typescript-eslint/scope-manager': 6.2.0 + '@typescript-eslint/type-utils': 6.2.0(eslint@8.46.0)(typescript@4.9.4) + '@typescript-eslint/utils': 6.2.0(eslint@8.46.0)(typescript@4.9.4) + '@typescript-eslint/visitor-keys': 6.2.0 + debug: 4.3.4(supports-color@8.1.1) + eslint: 8.46.0 + graphemer: 1.4.0 + ignore: 5.2.4 + natural-compare: 1.4.0 + natural-compare-lite: 1.4.0 + semver: 7.5.4 + ts-api-utils: 1.0.1(typescript@4.9.4) + typescript: 4.9.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/parser@6.2.0(eslint@8.46.0)(typescript@4.9.4): + resolution: {integrity: sha512-igVYOqtiK/UsvKAmmloQAruAdUHihsOCvplJpplPZ+3h4aDkC/UKZZNKgB6h93ayuYLuEymU3h8nF1xMRbh37g==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 6.2.0 + '@typescript-eslint/types': 6.2.0 + '@typescript-eslint/typescript-estree': 6.2.0(typescript@4.9.4) + '@typescript-eslint/visitor-keys': 6.2.0 + debug: 4.3.4(supports-color@8.1.1) + eslint: 8.46.0 + typescript: 4.9.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager@6.2.0: + resolution: {integrity: sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.2.0 + '@typescript-eslint/visitor-keys': 6.2.0 + dev: true + + /@typescript-eslint/type-utils@6.2.0(eslint@8.46.0)(typescript@4.9.4): + resolution: {integrity: sha512-DnGZuNU2JN3AYwddYIqrVkYW0uUQdv0AY+kz2M25euVNlujcN2u+rJgfJsBFlUEzBB6OQkUqSZPyuTLf2bP5mw==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 6.2.0(typescript@4.9.4) + '@typescript-eslint/utils': 6.2.0(eslint@8.46.0)(typescript@4.9.4) + debug: 4.3.4(supports-color@8.1.1) + eslint: 8.46.0 + ts-api-utils: 1.0.1(typescript@4.9.4) + typescript: 4.9.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types@6.2.0: + resolution: {integrity: sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==} + engines: {node: ^16.0.0 || >=18.0.0} + dev: true + + /@typescript-eslint/typescript-estree@6.2.0(typescript@4.9.4): + resolution: {integrity: sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 6.2.0 + '@typescript-eslint/visitor-keys': 6.2.0 + debug: 4.3.4(supports-color@8.1.1) + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.5.4 + ts-api-utils: 1.0.1(typescript@4.9.4) + typescript: 4.9.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils@6.2.0(eslint@8.46.0)(typescript@4.9.4): + resolution: {integrity: sha512-RCFrC1lXiX1qEZN8LmLrxYRhOkElEsPKTVSNout8DMzf8PeWoQG7Rxz2SadpJa3VSh5oYKGwt7j7X/VRg+Y3OQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.46.0) + '@types/json-schema': 7.0.12 + '@types/semver': 7.5.0 + '@typescript-eslint/scope-manager': 6.2.0 + '@typescript-eslint/types': 6.2.0 + '@typescript-eslint/typescript-estree': 6.2.0(typescript@4.9.4) + eslint: 8.46.0 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/visitor-keys@6.2.0: + resolution: {integrity: sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.2.0 + eslint-visitor-keys: 3.4.2 + dev: true + /@vitejs/plugin-vue@2.3.3(vite@2.9.9)(vue@3.2.36): resolution: {integrity: sha512-SmQLDyhz+6lGJhPELsBdzXGc+AcaT8stgkbiTFGpXPe8Tl1tJaBw1A6pxDqDuRsVkD8uscrkx3hA7QDOoKYtyw==} engines: {node: '>=12.0.0'} @@ -541,6 +803,34 @@ packages: vue-demi: 0.12.4(vue@3.2.36) dev: true + /acorn-jsx@5.3.2(acorn@8.10.0): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.10.0 + dev: true + + /acorn-walk@8.2.0: + resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn@8.10.0: + resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + 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.1: resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} engines: {node: '>=6'} @@ -566,6 +856,10 @@ packages: picomatch: 2.3.1 dev: true + /arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: true + /argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} dependencies: @@ -692,6 +986,11 @@ packages: engines: {node: '>=8'} dev: true + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + /camelcase@6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} @@ -776,6 +1075,10 @@ packages: engines: {node: '>=0.8'} dev: true + /create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: true + /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -807,6 +1110,10 @@ packages: engines: {node: '>=10'} dev: true + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + /defaults@1.0.3: resolution: {integrity: sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==} dependencies: @@ -823,6 +1130,11 @@ packages: engines: {node: '>=0.3.1'} dev: true + /diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: true + /diff@5.0.0: resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} engines: {node: '>=0.3.1'} @@ -835,6 +1147,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 + /electron-to-chromium@1.4.141: resolution: {integrity: sha512-mfBcbqc0qc6RlxrsIgLG2wCqkiPAjEezHxGTu7p3dHHFOurH4EjS9rFZndX5axC8264rI1Pcbw8uQP39oZckeA==} dev: true @@ -1072,16 +1391,125 @@ packages: engines: {node: '>=10'} dev: true + /eslint-config-prettier@8.9.0(eslint@8.46.0): + resolution: {integrity: sha512-+sbni7NfVXnOpnRadUA8S28AUlsZt9GjgFvABIRL9Hkn8KqNzOp+7Lw4QWtrwn20KzU3wqu1QoOj2m+7rKRqkA==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + dependencies: + eslint: 8.46.0 + dev: true + + /eslint-plugin-simple-import-sort@10.0.0(eslint@8.46.0): + resolution: {integrity: sha512-AeTvO9UCMSNzIHRkg8S6c3RPy5YEwKWSQPx3DYghLedo2ZQxowPFLGDN1AZ2evfg6r6mjBSZSLxLFsWSu3acsw==} + peerDependencies: + eslint: '>=5.0.0' + dependencies: + eslint: 8.46.0 + 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.2: + resolution: {integrity: sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint@8.46.0: + resolution: {integrity: sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.46.0) + '@eslint-community/regexpp': 4.6.2 + '@eslint/eslintrc': 2.1.1 + '@eslint/js': 8.46.0 + '@humanwhocodes/config-array': 0.11.10 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4(supports-color@8.1.1) + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.2 + espree: 9.6.1 + esquery: 1.5.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.20.0 + graphemer: 1.4.0 + ignore: 5.2.0 + 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.3 + 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.10.0 + acorn-jsx: 5.3.2(acorn@8.10.0) + eslint-visitor-keys: 3.4.2 + dev: true + /esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} hasBin: true dev: true + /esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + 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@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} 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'} @@ -1104,6 +1532,10 @@ packages: is-extendable: 0.1.1 dev: true + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + /fast-glob@3.2.11: resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==} engines: {node: '>=8.6.0'} @@ -1115,12 +1547,27 @@ packages: micromatch: 4.0.5 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.13.0: resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} 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.0.4 + dev: true + /fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} @@ -1136,11 +1583,23 @@ packages: path-exists: 4.0.0 dev: true + /flat-cache@3.0.4: + resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flatted: 3.2.7 + rimraf: 3.0.2 + dev: true + /flat@5.0.2: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true dev: true + /flatted@3.2.7: + resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} + dev: true + /follow-redirects@1.15.2: resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} engines: {node: '>=4.0'} @@ -1206,6 +1665,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@7.2.0: resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} dependencies: @@ -1217,6 +1683,13 @@ packages: path-is-absolute: 1.0.1 dev: true + /globals@13.20.0: + resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + /globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} @@ -1233,6 +1706,10 @@ packages: resolution: {integrity: sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==} dev: true + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true + /gray-matter@4.0.3: resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} engines: {node: '>=6.0'} @@ -1278,10 +1755,28 @@ packages: engines: {node: '>= 4'} dev: true + /ignore@5.2.4: + resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + engines: {node: '>= 4'} + dev: true + /immutable@4.0.0: resolution: {integrity: sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==} 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 + /inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} dependencies: @@ -1338,6 +1833,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@2.1.0: resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} engines: {node: '>=8'} @@ -1372,6 +1872,14 @@ packages: argparse: 2.0.1 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 + /json5@1.0.1: resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} hasBin: true @@ -1394,6 +1902,14 @@ packages: engines: {node: '>=0.10.0'} 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 + /linkify-it@4.0.1: resolution: {integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==} dependencies: @@ -1407,6 +1923,10 @@ packages: p-locate: 5.0.0 dev: true + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + /log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} @@ -1415,6 +1935,13 @@ packages: is-unicode-supported: 0.1.0 dev: true + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + /magic-string@0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} dependencies: @@ -1578,6 +2105,14 @@ packages: hasBin: true dev: true + /natural-compare-lite@1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + dev: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + /node-releases@2.0.5: resolution: {integrity: sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==} dev: true @@ -1612,6 +2147,18 @@ packages: mimic-fn: 2.1.0 dev: true + /optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + /ora@5.4.1: resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} engines: {node: '>=10'} @@ -1641,6 +2188,13 @@ packages: p-limit: 3.1.0 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 + /path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -1687,6 +2241,17 @@ packages: source-map-js: 1.0.2 dev: true + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /prettier@3.0.0: + resolution: {integrity: sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==} + engines: {node: '>=14'} + hasBin: true + dev: true + /prismjs@1.28.0: resolution: {integrity: sha512-8aaXdYvl1F7iC7Xm1spqSaY/OJBpYW3v+KJ+F17iYxvdc8sfjW194COK5wVhMZX45tGteiBQgdvD/nhxcRwylw==} engines: {node: '>=6'} @@ -1699,7 +2264,6 @@ packages: /punycode@2.1.1: resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} engines: {node: '>=6'} - dev: false /querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} @@ -1740,6 +2304,11 @@ packages: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} dev: false + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + /resolve@1.22.0: resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==} hasBin: true @@ -1762,6 +2331,13 @@ packages: engines: {iojs: '>=1.0.0', node: '>=0.10.0'} dev: true + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.0 + dev: true + /rollup@2.75.3: resolution: {integrity: sha512-YA29fLU6MAYSaDxIQYrGGOcbXlDmG96h0krGGYObroezcQ0KgEPM3+7MtKD/qeuUbFuAJXvKZee5dA1dpwq1PQ==} engines: {node: '>=10.0.0'} @@ -1803,6 +2379,14 @@ packages: engines: {node: '>=0.8.0'} dev: true + /semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + /serialize-javascript@6.0.0: resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} dependencies: @@ -1918,6 +2502,10 @@ packages: engines: {node: '>= 0.4'} dev: true + /text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + /to-fast-properties@2.0.0: resolution: {integrity: sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=} engines: {node: '>=4'} @@ -1944,6 +2532,15 @@ packages: url-parse: 1.5.10 dev: false + /ts-api-utils@1.0.1(typescript@4.9.4): + resolution: {integrity: sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==} + engines: {node: '>=16.13.0'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 4.9.4 + dev: true + /ts-debounce@4.0.0: resolution: {integrity: sha512-+1iDGY6NmOGidq7i7xZGA4cm8DAa6fqdYcvO5Z6yBevH++Bdo9Qt/mN0TzHUgcCcKv1gmh9+W5dHqz8pMWbCbg==} dev: true @@ -1961,6 +2558,37 @@ packages: tsconfig-paths: 3.14.1 dev: true + /ts-node@10.9.1(@types/node@18.11.17)(typescript@4.9.4): + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 18.11.17 + acorn: 8.10.0 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 4.9.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: true + /ts-node@7.0.1: resolution: {integrity: sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==} engines: {node: '>=4.2.0'} @@ -1987,6 +2615,18 @@ packages: dev: true optional: 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-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + /typescript@4.9.4: resolution: {integrity: sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==} engines: {node: '>=4.2.0'} @@ -2012,6 +2652,12 @@ packages: engines: {node: '>=4'} dev: true + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.1.1 + dev: true + /url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} dependencies: @@ -2023,6 +2669,10 @@ packages: resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=} dev: true + /v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: true + /vite@2.9.9: resolution: {integrity: sha512-ffaam+NgHfbEmfw/Vuh6BHKKlI/XIAhxE5QSS7gFLIngxg171mg1P3a4LSRME0z2ZU1ScxoKzphkipcYwSD5Ew==} engines: {node: '>=12.2.0'} @@ -2155,6 +2805,10 @@ packages: engines: {node: '>=10'} dev: true + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + /yargs-parser@20.2.4: resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} engines: {node: '>=10'} @@ -2188,6 +2842,11 @@ packages: engines: {node: '>=4'} dev: true + /yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: true + /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} diff --git a/src/@types/mocha.parallel.d.ts b/src/@types/mocha.parallel.d.ts index 45ac2d2..6da9ae7 100644 --- a/src/@types/mocha.parallel.d.ts +++ b/src/@types/mocha.parallel.d.ts @@ -1 +1 @@ -declare module "mocha.parallel" \ No newline at end of file +declare module "mocha.parallel" diff --git a/src/YTMusic.ts b/src/YTMusic.ts index 68f8d0b..6f20fac 100644 --- a/src/YTMusic.ts +++ b/src/YTMusic.ts @@ -9,8 +9,16 @@ import SearchParser from "./parsers/SearchParser" import SongParser from "./parsers/SongParser" import VideoParser from "./parsers/VideoParser" import { - AlbumDetailed, AlbumFull, ArtistDetailed, ArtistFull, PlaylistFull, SearchResult, SongDetailed, - SongFull, VideoDetailed, VideoFull + AlbumDetailed, + AlbumFull, + ArtistDetailed, + ArtistFull, + PlaylistFull, + SearchResult, + SongDetailed, + SongFull, + VideoDetailed, + VideoFull, } from "./schemas" import traverse from "./utils/traverse" import traverseList from "./utils/traverseList" @@ -33,9 +41,9 @@ export default class YTMusic { headers: { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36", - "Accept-Language": "en-US,en;q=0.5" + "Accept-Language": "en-US,en;q=0.5", }, - withCredentials: true + withCredentials: true, }) this.client.interceptors.request.use(req => { @@ -89,14 +97,16 @@ export default class YTMusic { .map(s => { try { return JSON.parse(s) - } catch {} + } catch { + return null + } }) .filter(j => !!j) for (const config of configs) { this.config = { ...this.config, - ...config + ...config, } } @@ -115,7 +125,7 @@ export default class YTMusic { private async constructRequest( endpoint: string, body: Record = {}, - query: Record = {} + query: Record = {}, ) { if (!this.config) { throw new Error("API not initialized. Make sure to call the initialize() method first") @@ -131,13 +141,13 @@ export default class YTMusic { "X-YouTube-Page-CL": this.config.PAGE_CL, "X-YouTube-Page-Label": this.config.PAGE_BUILD_LABEL, "X-YouTube-Utc-Offset": String(-new Date().getTimezoneOffset()), - "X-YouTube-Time-Zone": new Intl.DateTimeFormat().resolvedOptions().timeZone + "X-YouTube-Time-Zone": new Intl.DateTimeFormat().resolvedOptions().timeZone, } const searchParams = new URLSearchParams({ ...query, alt: "json", - key: this.config.INNERTUBE_API_KEY! + key: this.config.INNERTUBE_API_KEY!, }) const res = await this.client.post( @@ -154,42 +164,42 @@ export default class YTMusic { hl: this.config.HL, locationInfo: { locationPermissionAuthorizationStatus: - "LOCATION_PERMISSION_AUTHORIZATION_STATUS_UNSUPPORTED" + "LOCATION_PERMISSION_AUTHORIZATION_STATUS_UNSUPPORTED", }, musicAppInfo: { musicActivityMasterSwitch: "MUSIC_ACTIVITY_MASTER_SWITCH_INDETERMINATE", musicLocationMasterSwitch: "MUSIC_LOCATION_MASTER_SWITCH_INDETERMINATE", - pwaInstallabilityStatus: "PWA_INSTALLABILITY_STATUS_UNKNOWN" + pwaInstallabilityStatus: "PWA_INSTALLABILITY_STATUS_UNKNOWN", }, - utcOffsetMinutes: -new Date().getTimezoneOffset() + utcOffsetMinutes: -new Date().getTimezoneOffset(), }, request: { internalExperimentFlags: [ { key: "force_music_enable_outertube_tastebuilder_browse", - value: "true" + value: "true", }, { key: "force_music_enable_outertube_playlist_detail_browse", - value: "true" + value: "true", }, { key: "force_music_enable_outertube_search_suggestions", - value: "true" - } + value: "true", + }, ], - sessionIndex: {} + sessionIndex: {}, }, user: { - enableSafetyMode: false - } + enableSafetyMode: false, + }, }, - ...body + ...body, }, { responseType: "json", - headers - } + headers, + }, ) return "responseContext" in res.data ? res.data : res @@ -204,9 +214,9 @@ export default class YTMusic { public async getSearchSuggestions(query: string): Promise { return traverseList( await this.constructRequest("music/get_search_suggestions", { - input: query + input: query, }), - "query" + "query", ) } @@ -218,7 +228,7 @@ export default class YTMusic { public async search(query: string): Promise[]> { const searchData = await this.constructRequest("search", { query, - params: null + params: null, }) return traverseList(searchData, "musicResponsiveListItemRenderer") @@ -234,11 +244,11 @@ export default class YTMusic { public async searchSongs(query: string): Promise[]> { const searchData = await this.constructRequest("search", { query, - params: "Eg-KAQwIARAAGAAgACgAMABqChAEEAMQCRAFEAo%3D" + params: "Eg-KAQwIARAAGAAgACgAMABqChAEEAMQCRAFEAo%3D", }) return traverseList(searchData, "musicResponsiveListItemRenderer").map( - SongParser.parseSearchResult + SongParser.parseSearchResult, ) } @@ -250,11 +260,11 @@ export default class YTMusic { public async searchVideos(query: string): Promise[]> { const searchData = await this.constructRequest("search", { query, - params: "Eg-KAQwIABABGAAgACgAMABqChAEEAMQCRAFEAo%3D" + params: "Eg-KAQwIABABGAAgACgAMABqChAEEAMQCRAFEAo%3D", }) return traverseList(searchData, "musicResponsiveListItemRenderer").map( - VideoParser.parseSearchResult + VideoParser.parseSearchResult, ) } @@ -266,11 +276,11 @@ export default class YTMusic { public async searchArtists(query: string): Promise[]> { const searchData = await this.constructRequest("search", { query, - params: "Eg-KAQwIABAAGAAgASgAMABqChAEEAMQCRAFEAo%3D" + params: "Eg-KAQwIABAAGAAgASgAMABqChAEEAMQCRAFEAo%3D", }) return traverseList(searchData, "musicResponsiveListItemRenderer").map( - ArtistParser.parseSearchResult + ArtistParser.parseSearchResult, ) } @@ -282,11 +292,11 @@ export default class YTMusic { public async searchAlbums(query: string): Promise[]> { const searchData = await this.constructRequest("search", { query, - params: "Eg-KAQwIABAAGAEgACgAMABqChAEEAMQCRAFEAo%3D" + params: "Eg-KAQwIABAAGAEgACgAMABqChAEEAMQCRAFEAo%3D", }) return traverseList(searchData, "musicResponsiveListItemRenderer").map( - AlbumParser.parseSearchResult + AlbumParser.parseSearchResult, ) } @@ -298,11 +308,11 @@ export default class YTMusic { public async searchPlaylists(query: string): Promise[]> { const searchData = await this.constructRequest("search", { query, - params: "Eg-KAQwIABAAGAAgACgBMABqChAEEAMQCRAFEAo%3D" + params: "Eg-KAQwIABAAGAAgACgBMABqChAEEAMQCRAFEAo%3D", }) return traverseList(searchData, "musicResponsiveListItemRenderer").map( - PlaylistParser.parseSearchResult + PlaylistParser.parseSearchResult, ) } @@ -344,7 +354,7 @@ export default class YTMusic { */ public async getArtist(artistId: string): Promise> { const data = await this.constructRequest("browse", { - browseId: artistId + browseId: artistId, }) return ArtistParser.parse(data, artistId) @@ -358,25 +368,25 @@ export default class YTMusic { */ public async getArtistSongs(artistId: string): Promise[]> { const artistData = await this.constructRequest("browse", { - browseId: artistId + browseId: artistId, }) const browseToken = traverse(artistData, "musicShelfRenderer", "title", "browseId") if (browseToken instanceof Array) return [] const songsData = await this.constructRequest("browse", { - browseId: browseToken + browseId: browseToken, }) const continueToken = traverse(songsData, "continuation") const moreSongsData = await this.constructRequest( "browse", {}, - { continuation: continueToken } + { continuation: continueToken }, ) return [ ...traverseList(songsData, "musicResponsiveListItemRenderer"), - ...traverseList(moreSongsData, "musicResponsiveListItemRenderer") + ...traverseList(moreSongsData, "musicResponsiveListItemRenderer"), ].map(SongParser.parseArtistSong) } @@ -388,7 +398,7 @@ export default class YTMusic { */ public async getArtistAlbums(artistId: string): Promise[]> { const artistData = await this.constructRequest("browse", { - browseId: artistId + browseId: artistId, }) const artistAlbumsData = traverseList(artistData, "musicCarouselShelfRenderer")[0] const browseBody = traverse(artistAlbumsData, "moreContentButton", "browseEndpoint") @@ -398,8 +408,8 @@ export default class YTMusic { return traverseList(albumsData, "musicTwoRowItemRenderer").map(item => AlbumParser.parseArtistAlbum(item, { artistId, - name: traverseString(albumsData, "header", "runs", "text")() - }) + name: traverseString(albumsData, "header", "runs", "text")(), + }), ) } @@ -411,7 +421,7 @@ export default class YTMusic { */ public async getAlbum(albumId: string): Promise> { const data = await this.constructRequest("browse", { - browseId: albumId + browseId: albumId, }) return AlbumParser.parse(data, albumId) @@ -426,7 +436,7 @@ export default class YTMusic { public async getPlaylist(playlistId: string): Promise> { if (playlistId.startsWith("PL")) playlistId = "VL" + playlistId const data = await this.constructRequest("browse", { - browseId: playlistId + browseId: playlistId, }) return PlaylistParser.parse(data, playlistId) @@ -441,18 +451,16 @@ export default class YTMusic { public async getPlaylistVideos(playlistId: string): Promise[]> { if (playlistId.startsWith("PL")) playlistId = "VL" + playlistId const playlistData = await this.constructRequest("browse", { - browseId: playlistId + browseId: playlistId, }) const songs = traverseList( playlistData, "musicPlaylistShelfRenderer", - "musicResponsiveListItemRenderer" + "musicResponsiveListItemRenderer", ) let continuation = traverse(playlistData, "continuation") - while (true) { - if (continuation instanceof Array) break - + while (!(continuation instanceof Array)) { const songsData = await this.constructRequest("browse", {}, { continuation }) songs.push(...traverseList(songsData, "musicResponsiveListItemRenderer")) continuation = traverse(songsData, "continuation") diff --git a/src/__tests__/traversing.spec.ts b/src/__tests__/traversing.spec.ts index 383e94e..4494d48 100644 --- a/src/__tests__/traversing.spec.ts +++ b/src/__tests__/traversing.spec.ts @@ -1,12 +1,19 @@ +import { equal } from "assert" import describeParallel from "mocha.parallel" import { z } from "zod" import { - AlbumDetailed, AlbumFull, ArtistDetailed, ArtistFull, PlaylistFull, SongDetailed, SongFull, - VideoDetailed, VideoFull + AlbumDetailed, + AlbumFull, + ArtistDetailed, + ArtistFull, + PlaylistFull, + SongDetailed, + SongFull, + VideoDetailed, + VideoFull, } from "../schemas" import YTMusic from "../YTMusic" -import { equal } from "assert" const errors = []>[] const queries = ["Lilac", "Weekend", "Eill", "Eminem", "Lisa Hannigan"] @@ -61,8 +68,8 @@ queries.forEach(query => { AlbumDetailed.or(ArtistDetailed) .or(PlaylistFull) .or(SongDetailed) - .or(VideoDetailed) - ) + .or(VideoDetailed), + ), ) }) diff --git a/src/index.ts b/src/index.ts index 3a82120..3cf8397 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,7 +13,7 @@ export type { SongFull, ThumbnailFull, VideoDetailed, - VideoFull + VideoFull, } from "./schemas" export default YTMusic diff --git a/src/parsers/AlbumParser.ts b/src/parsers/AlbumParser.ts index 7250bbc..469c15a 100644 --- a/src/parsers/AlbumParser.ts +++ b/src/parsers/AlbumParser.ts @@ -8,13 +8,13 @@ export default class AlbumParser { public static parse(data: any, albumId: string): AlbumFull { const albumBasic: AlbumBasic = { albumId, - name: traverseString(data, "header", "title", "text")() + name: traverseString(data, "header", "title", "text")(), } const artists: ArtistBasic[] = traverseList(data, "header", "subtitle", "runs") .filter(run => "navigationEndpoint" in run) .map(run => ({ artistId: traverseString(run, "browseId")(), - name: traverseString(run, "text")() + name: traverseString(run, "text")(), })) const thumbnails = traverseList(data, "header", "thumbnails") @@ -25,15 +25,15 @@ export default class AlbumParser { playlistId: traverseString(data, "buttonRenderer", "playlistId")(), artists, year: AlbumParser.processYear( - traverseString(data, "header", "subtitle", "text")(-1) + traverseString(data, "header", "subtitle", "text")(-1), ), thumbnails, description: traverseString(data, "description", "text")(), songs: traverseList(data, "musicResponsiveListItemRenderer").map(item => - SongParser.parseAlbumSong(item, artists, albumBasic, thumbnails) - ) + SongParser.parseAlbumSong(item, artists, albumBasic, thumbnails), + ), }, - AlbumFull + AlbumFull, ) } @@ -49,13 +49,13 @@ export default class AlbumParser { .filter(run => "navigationEndpoint" in run) .map(run => ({ artistId: traverseString(run, "browseId")(), - name: traverseString(run, "text")() + name: traverseString(run, "text")(), })), year: AlbumParser.processYear(traverseString(flexColumns[1], "runs", "text")(-1)), name: traverseString(flexColumns[0], "runs", "text")(), - thumbnails: traverseList(item, "thumbnails") + thumbnails: traverseList(item, "thumbnails"), }, - AlbumDetailed + AlbumDetailed, ) } @@ -68,9 +68,9 @@ export default class AlbumParser { name: traverseString(item, "title", "text")(), artists: [artistBasic], year: AlbumParser.processYear(traverseString(item, "subtitle", "text")(-1)), - thumbnails: traverseList(item, "thumbnails") + thumbnails: traverseList(item, "thumbnails"), }, - AlbumDetailed + AlbumDetailed, ) } @@ -83,9 +83,9 @@ export default class AlbumParser { name: traverseString(item, "title", "text")(), artists: [artistBasic], year: AlbumParser.processYear(traverseString(item, "subtitle", "text")(-1)), - thumbnails: traverseList(item, "thumbnails") + thumbnails: traverseList(item, "thumbnails"), }, - AlbumDetailed + AlbumDetailed, ) } diff --git a/src/parsers/ArtistParser.ts b/src/parsers/ArtistParser.ts index ceb78d5..53954d4 100644 --- a/src/parsers/ArtistParser.ts +++ b/src/parsers/ArtistParser.ts @@ -1,5 +1,3 @@ - - import { ArtistBasic, ArtistDetailed, ArtistFull } from "../schemas" import checkType from "../utils/checkType" import traverseList from "../utils/traverseList" @@ -12,7 +10,7 @@ export default class ArtistParser { public static parse(data: any, artistId: string): ArtistFull { const artistBasic: ArtistBasic = { artistId, - name: traverseString(data, "header", "title", "text")() + name: traverseString(data, "header", "title", "text")(), } const description = traverseString(data, "header", "description", "text")() @@ -24,28 +22,28 @@ export default class ArtistParser { thumbnails: traverseList(data, "header", "thumbnails"), description, topSongs: traverseList(data, "musicShelfRenderer", "contents").map(item => - SongParser.parseArtistTopSong(item, artistBasic) + SongParser.parseArtistTopSong(item, artistBasic), ), topAlbums: traverseList(data, "musicCarouselShelfRenderer") ?.at(0) ?.contents.map((item: any) => - AlbumParser.parseArtistTopAlbum(item, artistBasic) + AlbumParser.parseArtistTopAlbum(item, artistBasic), ) ?? [], topSingles: traverseList(data, "musicCarouselShelfRenderer") ?.at(1) ?.contents.map((item: any) => - AlbumParser.parseArtistTopAlbum(item, artistBasic) + AlbumParser.parseArtistTopAlbum(item, artistBasic), ) ?? [], topVideos: traverseList(data, "musicCarouselShelfRenderer") ?.at(2) ?.contents.map((item: any) => - VideoParser.parseArtistTopVideo(item, artistBasic) - ) ?? [] + VideoParser.parseArtistTopVideo(item, artistBasic), + ) ?? [], }, - ArtistFull + ArtistFull, ) } @@ -57,9 +55,9 @@ export default class ArtistParser { type: "ARTIST", artistId: traverseString(item, "browseId")(), name: traverseString(flexColumns[0], "runs", "text")(), - thumbnails: traverseList(item, "thumbnails") + thumbnails: traverseList(item, "thumbnails"), }, - ArtistDetailed + ArtistDetailed, ) } } diff --git a/src/parsers/Parser.ts b/src/parsers/Parser.ts index e09e636..225d3fd 100644 --- a/src/parsers/Parser.ts +++ b/src/parsers/Parser.ts @@ -18,7 +18,7 @@ export default class Parser { K: number * 1000, M: number * 1000 * 1000, B: number * 1000 * 1000 * 1000, - T: number * 1000 * 1000 * 1000 * 1000 + T: number * 1000 * 1000 * 1000 * 1000, }[multiplier!] || NaN ) } else { diff --git a/src/parsers/PlaylistParser.ts b/src/parsers/PlaylistParser.ts index c0dae2e..7894b93 100644 --- a/src/parsers/PlaylistParser.ts +++ b/src/parsers/PlaylistParser.ts @@ -12,11 +12,11 @@ export default class PlaylistParser { name: traverseString(data, "header", "title", "text")(), artist: { artistId: traverseString(data, "header", "subtitle", "browseId")(), - name: traverseString(data, "header", "subtitle", "text")(2) + name: traverseString(data, "header", "subtitle", "text")(2), }, - thumbnails: traverseList(data, "header", "thumbnails") + thumbnails: traverseList(data, "header", "thumbnails"), }, - PlaylistFull + PlaylistFull, ) } @@ -30,11 +30,11 @@ export default class PlaylistParser { name: traverseString(flexColumns[0], "runs", "text")(), artist: { artistId: traverseString(flexColumns[1], "browseId")(), - name: traverseString(flexColumns[1], "runs", "text")(-3) + name: traverseString(flexColumns[1], "runs", "text")(-3), }, - thumbnails: traverseList(item, "thumbnails") + thumbnails: traverseList(item, "thumbnails"), }, - PlaylistFull + PlaylistFull, ) } } diff --git a/src/parsers/SearchParser.ts b/src/parsers/SearchParser.ts index 8456cb1..7a59fe9 100644 --- a/src/parsers/SearchParser.ts +++ b/src/parsers/SearchParser.ts @@ -17,7 +17,7 @@ export default class SearchParser { | "Single" | "Album" | "Playlist" - + const parsers = { Song: SongParser.parseSearchResult, Video: VideoParser.parseSearchResult, @@ -25,7 +25,7 @@ export default class SearchParser { EP: AlbumParser.parseSearchResult, Single: AlbumParser.parseSearchResult, Album: AlbumParser.parseSearchResult, - Playlist: PlaylistParser.parseSearchResult + Playlist: PlaylistParser.parseSearchResult, } if (parsers[type]) { diff --git a/src/parsers/SongParser.ts b/src/parsers/SongParser.ts index 28ae8ba..425a9e3 100644 --- a/src/parsers/SongParser.ts +++ b/src/parsers/SongParser.ts @@ -14,16 +14,16 @@ export default class SongParser { artists: [ { artistId: traverseString(data, "videoDetails", "channelId")(), - name: traverseString(data, "author")() - } + name: traverseString(data, "author")(), + }, ], duration: +traverseString(data, "videoDetails", "lengthSeconds")(), thumbnails: traverseList(data, "videoDetails", "thumbnails"), description: traverseString(data, "description")(), formats: traverseList(data, "streamingData", "formats"), - adaptiveFormats: traverseList(data, "streamingData", "adaptiveFormats") + adaptiveFormats: traverseList(data, "streamingData", "adaptiveFormats"), }, - SongFull + SongFull, ) } @@ -39,17 +39,17 @@ export default class SongParser { .filter(run => "navigationEndpoint" in run) .map(run => ({ artistId: traverseString(run, "browseId")(), - name: traverseString(run, "text")() + name: traverseString(run, "text")(), })) .slice(0, -1), album: { albumId: traverseString(flexColumns[1], "runs", "browseId")(-1), - name: traverseString(flexColumns[1], "runs", "text")(-3) + name: traverseString(flexColumns[1], "runs", "text")(-3), }, duration: Parser.parseDuration(traverseString(flexColumns[1], "runs", "text")(-1)), - thumbnails: traverseList(item, "thumbnails") + thumbnails: traverseList(item, "thumbnails"), }, - SongDetailed + SongDetailed, ) } @@ -66,24 +66,24 @@ export default class SongParser { .filter(run => "navigationEndpoint" in run) .map(run => ({ artistId: traverseString(run, "browseId")(), - name: traverseString(run, "text")() + name: traverseString(run, "text")(), })), album: { albumId: traverseString(flexColumns[2], "browseId")(), - name: traverseString(flexColumns[2], "runs", "text")() + name: traverseString(flexColumns[2], "runs", "text")(), }, duration: Parser.parseDuration( - traverseString(item, "fixedColumns", "runs", "text")() + traverseString(item, "fixedColumns", "runs", "text")(), ), - thumbnails: traverseList(item, "thumbnails") + thumbnails: traverseList(item, "thumbnails"), }, - SongDetailed + SongDetailed, ) } public static parseArtistTopSong( item: any, - artistBasic: ArtistBasic + artistBasic: ArtistBasic, ): Omit { const flexColumns = traverseList(item, "flexColumns") const videoId = traverseString(item, "playlistItemData", "videoId")() @@ -96,11 +96,11 @@ export default class SongParser { artists: [artistBasic], album: { albumId: traverseString(flexColumns[2], "browseId")(), - name: traverseString(flexColumns[2], "runs", "text")() + name: traverseString(flexColumns[2], "runs", "text")(), }, - thumbnails: traverseList(item, "thumbnails") + thumbnails: traverseList(item, "thumbnails"), }, - SongDetailed.omit({ duration: true }) + SongDetailed.omit({ duration: true }), ) } @@ -108,7 +108,7 @@ export default class SongParser { item: any, artists: ArtistBasic[], albumBasic: AlbumBasic, - thumbnails: ThumbnailFull[] + thumbnails: ThumbnailFull[], ): SongDetailed { const flexColumns = traverseList(item, "flexColumns") const videoId = traverseString(item, "playlistItemData", "videoId")() @@ -121,11 +121,11 @@ export default class SongParser { artists, album: albumBasic, duration: Parser.parseDuration( - traverseString(item, "fixedColumns", "runs", "text")() + traverseString(item, "fixedColumns", "runs", "text")(), ), - thumbnails + thumbnails, }, - SongDetailed + SongDetailed, ) } } diff --git a/src/parsers/VideoParser.ts b/src/parsers/VideoParser.ts index fe35d20..233c18a 100644 --- a/src/parsers/VideoParser.ts +++ b/src/parsers/VideoParser.ts @@ -14,8 +14,8 @@ export default class VideoParser { artists: [ { artistId: traverseString(data, "videoDetails", "channelId")(), - name: traverseString(data, "author")() - } + name: traverseString(data, "author")(), + }, ], duration: +traverseString(data, "videoDetails", "lengthSeconds")(), thumbnails: traverseList(data, "videoDetails", "thumbnails"), @@ -23,7 +23,7 @@ export default class VideoParser { unlisted: traverse(data, "unlisted"), familySafe: traverse(data, "familySafe"), paid: traverse(data, "paid"), - tags: traverseList(data, "tags") + tags: traverseList(data, "tags"), } } @@ -39,23 +39,23 @@ export default class VideoParser { .filter(run => "navigationEndpoint" in run) .map(run => ({ artistId: traverseString(run, "browseId")(), - name: traverseString(run, "text")() + name: traverseString(run, "text")(), })), duration: Parser.parseDuration(traverseString(flexColumns[1], "text")(-1)), - thumbnails: traverseList(item, "thumbnails") + thumbnails: traverseList(item, "thumbnails"), } } public static parseArtistTopVideo( item: any, - artistBasic: ArtistBasic + artistBasic: ArtistBasic, ): Omit { return { type: "VIDEO", videoId: traverseString(item, "videoId")(), name: traverseString(item, "runs", "text")(), artists: [artistBasic], - thumbnails: traverseList(item, "thumbnails") + thumbnails: traverseList(item, "thumbnails"), } } @@ -74,14 +74,14 @@ export default class VideoParser { .filter(run => "navigationEndpoint" in run) .map(run => ({ artistId: traverseString(run, "browseId")(), - name: traverseString(run, "text")() + name: traverseString(run, "text")(), })), duration: Parser.parseDuration( - traverseString(item, "fixedColumns", "runs", "text")() + traverseString(item, "fixedColumns", "runs", "text")(), ), - thumbnails: traverseList(item, "thumbnails") + thumbnails: traverseList(item, "thumbnails"), }, - VideoDetailed + VideoDetailed, ) } } diff --git a/src/schemas.ts b/src/schemas.ts index d0f1b7e..38a40eb 100644 --- a/src/schemas.ts +++ b/src/schemas.ts @@ -4,19 +4,19 @@ export type ThumbnailFull = z.infer export const ThumbnailFull = z.object({ url: z.string(), width: z.number(), - height: z.number() + height: z.number(), }) export type ArtistBasic = z.infer export const ArtistBasic = z.object({ artistId: z.string(), - name: z.string() + name: z.string(), }) export type AlbumBasic = z.infer export const AlbumBasic = z.object({ albumId: z.string(), - name: z.string() + name: z.string(), }) export type SongDetailed = z.infer @@ -27,7 +27,7 @@ export const SongDetailed = z.object({ artists: z.array(ArtistBasic), album: AlbumBasic, duration: z.number(), - thumbnails: z.array(ThumbnailFull) + thumbnails: z.array(ThumbnailFull), }) export type VideoDetailed = z.infer @@ -37,7 +37,7 @@ export const VideoDetailed = z.object({ name: z.string(), artists: z.array(ArtistBasic), duration: z.number(), - thumbnails: z.array(ThumbnailFull) + thumbnails: z.array(ThumbnailFull), }) export type ArtistDetailed = z.infer @@ -45,7 +45,7 @@ export const ArtistDetailed = z.object({ artistId: z.string(), name: z.string(), type: z.literal("ARTIST"), - thumbnails: z.array(ThumbnailFull) + thumbnails: z.array(ThumbnailFull), }) export type AlbumDetailed = z.infer @@ -56,7 +56,7 @@ export const AlbumDetailed = z.object({ name: z.string(), artists: z.array(ArtistBasic), year: z.number().nullable(), - thumbnails: z.array(ThumbnailFull) + thumbnails: z.array(ThumbnailFull), }) export type SongFull = z.infer @@ -69,7 +69,7 @@ export const SongFull = z.object({ thumbnails: z.array(ThumbnailFull), description: z.string(), formats: z.array(z.any()), - adaptiveFormats: z.array(z.any()) + adaptiveFormats: z.array(z.any()), }) export type VideoFull = z.infer @@ -84,7 +84,7 @@ export const VideoFull = z.object({ unlisted: z.boolean(), familySafe: z.boolean(), paid: z.boolean(), - tags: z.array(z.string()) + tags: z.array(z.string()), }) export type ArtistFull = z.infer @@ -97,7 +97,7 @@ export const ArtistFull = z.object({ topSongs: z.array(SongDetailed.omit({ duration: true })), topAlbums: z.array(AlbumDetailed), topSingles: z.array(AlbumDetailed), - topVideos: z.array(VideoDetailed.omit({ duration: true })) + topVideos: z.array(VideoDetailed.omit({ duration: true })), }) export type AlbumFull = z.infer @@ -110,7 +110,7 @@ export const AlbumFull = z.object({ year: z.number().nullable(), thumbnails: z.array(ThumbnailFull), description: z.string(), - songs: z.array(SongDetailed) + songs: z.array(SongDetailed), }) export type PlaylistFull = z.infer @@ -119,7 +119,7 @@ export const PlaylistFull = z.object({ playlistId: z.string(), name: z.string(), artist: ArtistBasic, - thumbnails: z.array(ThumbnailFull) + thumbnails: z.array(ThumbnailFull), }) export type SearchResult = z.infer diff --git a/src/utils/checkType.ts b/src/utils/checkType.ts index 465b85c..267aa23 100644 --- a/src/utils/checkType.ts +++ b/src/utils/checkType.ts @@ -13,11 +13,11 @@ export default (data: z.infer, schema: T): z.infer => { schema: zodtojson(schema), data, - error: result.error + error: result.error, }, null, - 2 - ) + 2, + ), ) } return data diff --git a/src/utils/traverse.ts b/src/utils/traverse.ts index 1022423..92be35c 100644 --- a/src/utils/traverse.ts +++ b/src/utils/traverse.ts @@ -1,6 +1,6 @@ const traverse = (data: any, ...keys: string[]) => { const again = (data: any, key: string): any => { - let res = [] + const res = [] if (data instanceof Object && key in data) { res.push(data[key]) @@ -12,7 +12,7 @@ const traverse = (data: any, ...keys: string[]) => { res.push( ...Object.keys(data) .map(k => again(data[k], key)) - .flat() + .flat(), ) } diff --git a/src/utils/traverseList.ts b/src/utils/traverseList.ts index 5f5c644..3c12592 100644 --- a/src/utils/traverseList.ts +++ b/src/utils/traverseList.ts @@ -4,4 +4,4 @@ export default (data: any, ...keys: string[]): any[] => { const value = traverse(data, ...keys) const flatValue = [value].flat() return flatValue -} \ No newline at end of file +} diff --git a/src/utils/traverseString.ts b/src/utils/traverseString.ts index 6d10a32..c679d4e 100644 --- a/src/utils/traverseString.ts +++ b/src/utils/traverseString.ts @@ -1,7 +1,8 @@ import traverse from "./traverse" -export default (data: any, ...keys: string[]) => (index = 0): string => { - const value = traverse(data, ...keys) - const flatValue = [value].flat().at(index) - return flatValue || "" -} +export default (data: any, ...keys: string[]) => + (index = 0): string => { + const value = traverse(data, ...keys) + const flatValue = [value].flat().at(index) + return flatValue || "" + }