diff --git a/api_tests/package.json b/api_tests/package.json index 75ef362f8..60adac43c 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -20,16 +20,16 @@ }, "devDependencies": { "@types/jest": "^29.5.12", - "@types/node": "^20.11.27", - "@typescript-eslint/eslint-plugin": "^7.2.0", - "@typescript-eslint/parser": "^7.2.0", + "@types/node": "^20.12.4", + "@typescript-eslint/eslint-plugin": "^7.5.0", + "@typescript-eslint/parser": "^7.5.0", "download-file-sync": "^1.0.4", "eslint": "^8.57.0", "eslint-plugin-prettier": "^5.1.3", "jest": "^29.5.0", - "lemmy-js-client": "0.19.4-alpha.13", + "lemmy-js-client": "0.19.4-alpha.16", "prettier": "^3.2.5", "ts-jest": "^29.1.0", - "typescript": "^5.4.2" + "typescript": "^5.4.4" } } diff --git a/api_tests/pnpm-lock.yaml b/api_tests/pnpm-lock.yaml index 7b8c05328..81508d740 100644 --- a/api_tests/pnpm-lock.yaml +++ b/api_tests/pnpm-lock.yaml @@ -9,14 +9,14 @@ devDependencies: specifier: ^29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.11.27 - version: 20.11.27 + specifier: ^20.12.4 + version: 20.12.4 '@typescript-eslint/eslint-plugin': - specifier: ^7.2.0 - version: 7.2.0(@typescript-eslint/parser@7.2.0)(eslint@8.57.0)(typescript@5.4.2) + specifier: ^7.5.0 + version: 7.5.0(@typescript-eslint/parser@7.5.0)(eslint@8.57.0)(typescript@5.4.4) '@typescript-eslint/parser': - specifier: ^7.2.0 - version: 7.2.0(eslint@8.57.0)(typescript@5.4.2) + specifier: ^7.5.0 + version: 7.5.0(eslint@8.57.0)(typescript@5.4.4) download-file-sync: specifier: ^1.0.4 version: 1.0.4 @@ -28,19 +28,19 @@ devDependencies: version: 5.1.3(eslint@8.57.0)(prettier@3.2.5) jest: specifier: ^29.5.0 - version: 29.7.0(@types/node@20.11.27) + version: 29.7.0(@types/node@20.12.4) lemmy-js-client: - specifier: 0.19.4-alpha.13 - version: 0.19.4-alpha.13 + specifier: 0.19.4-alpha.16 + version: 0.19.4-alpha.16 prettier: specifier: ^3.2.5 version: 3.2.5 ts-jest: specifier: ^29.1.0 - version: 29.1.2(@babel/core@7.23.9)(jest@29.7.0)(typescript@5.4.2) + version: 29.1.2(@babel/core@7.23.9)(jest@29.7.0)(typescript@5.4.4) typescript: - specifier: ^5.4.2 - version: 5.4.2 + specifier: ^5.4.4 + version: 5.4.4 packages: @@ -464,7 +464,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.27 + '@types/node': 20.12.4 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -485,14 +485,14 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.27 + '@types/node': 20.12.4 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.11.27) + jest-config: 29.7.0(@types/node@20.12.4) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -520,7 +520,7 @@ packages: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.27 + '@types/node': 20.12.4 jest-mock: 29.7.0 dev: true @@ -547,7 +547,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.11.27 + '@types/node': 20.12.4 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -580,7 +580,7 @@ packages: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.22 - '@types/node': 20.11.27 + '@types/node': 20.12.4 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -668,7 +668,7 @@ packages: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.11.27 + '@types/node': 20.12.4 '@types/yargs': 17.0.32 chalk: 4.1.2 dev: true @@ -777,7 +777,7 @@ packages: /@types/graceful-fs@4.1.9: resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} dependencies: - '@types/node': 20.11.27 + '@types/node': 20.12.4 dev: true /@types/istanbul-lib-coverage@2.0.6: @@ -807,8 +807,8 @@ packages: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: true - /@types/node@20.11.27: - resolution: {integrity: sha512-qyUZfMnCg1KEz57r7pzFtSGt49f6RPkPBis3Vo4PbS7roQEDn22hiHzl/Lo1q4i4hDEgBJmBF/NTNg2XR0HbFg==} + /@types/node@20.12.4: + resolution: {integrity: sha512-E+Fa9z3wSQpzgYQdYmme5X3OTuejnnTx88A6p6vkkJosR3KBz+HpE3kqNm98VE6cfLFcISx7zW7MsJkH6KwbTw==} dependencies: undici-types: 5.26.5 dev: true @@ -831,9 +831,9 @@ packages: '@types/yargs-parser': 21.0.3 dev: true - /@typescript-eslint/eslint-plugin@7.2.0(@typescript-eslint/parser@7.2.0)(eslint@8.57.0)(typescript@5.4.2): - resolution: {integrity: sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw==} - engines: {node: ^16.0.0 || >=18.0.0} + /@typescript-eslint/eslint-plugin@7.5.0(@typescript-eslint/parser@7.5.0)(eslint@8.57.0)(typescript@5.4.4): + resolution: {integrity: sha512-HpqNTH8Du34nLxbKgVMGljZMG0rJd2O9ecvr2QLYp+7512ty1j42KnsFwspPXg1Vh8an9YImf6CokUBltisZFQ==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: '@typescript-eslint/parser': ^7.0.0 eslint: ^8.56.0 @@ -843,26 +843,26 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.4.2) - '@typescript-eslint/scope-manager': 7.2.0 - '@typescript-eslint/type-utils': 7.2.0(eslint@8.57.0)(typescript@5.4.2) - '@typescript-eslint/utils': 7.2.0(eslint@8.57.0)(typescript@5.4.2) - '@typescript-eslint/visitor-keys': 7.2.0 + '@typescript-eslint/parser': 7.5.0(eslint@8.57.0)(typescript@5.4.4) + '@typescript-eslint/scope-manager': 7.5.0 + '@typescript-eslint/type-utils': 7.5.0(eslint@8.57.0)(typescript@5.4.4) + '@typescript-eslint/utils': 7.5.0(eslint@8.57.0)(typescript@5.4.4) + '@typescript-eslint/visitor-keys': 7.5.0 debug: 4.3.4 eslint: 8.57.0 graphemer: 1.4.0 ignore: 5.3.1 natural-compare: 1.4.0 semver: 7.6.0 - ts-api-utils: 1.3.0(typescript@5.4.2) - typescript: 5.4.2 + ts-api-utils: 1.3.0(typescript@5.4.4) + typescript: 5.4.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.2): - resolution: {integrity: sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==} - engines: {node: ^16.0.0 || >=18.0.0} + /@typescript-eslint/parser@7.5.0(eslint@8.57.0)(typescript@5.4.4): + resolution: {integrity: sha512-cj+XGhNujfD2/wzR1tabNsidnYRaFfEkcULdcIyVBYcXjBvBKOes+mpMBP7hMpOyk+gBcfXsrg4NBGAStQyxjQ==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 typescript: '*' @@ -870,28 +870,28 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 7.2.0 - '@typescript-eslint/types': 7.2.0 - '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.4.2) - '@typescript-eslint/visitor-keys': 7.2.0 + '@typescript-eslint/scope-manager': 7.5.0 + '@typescript-eslint/types': 7.5.0 + '@typescript-eslint/typescript-estree': 7.5.0(typescript@5.4.4) + '@typescript-eslint/visitor-keys': 7.5.0 debug: 4.3.4 eslint: 8.57.0 - typescript: 5.4.2 + typescript: 5.4.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager@7.2.0: - resolution: {integrity: sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==} - engines: {node: ^16.0.0 || >=18.0.0} + /@typescript-eslint/scope-manager@7.5.0: + resolution: {integrity: sha512-Z1r7uJY0MDeUlql9XJ6kRVgk/sP11sr3HKXn268HZyqL7i4cEfrdFuSSY/0tUqT37l5zT0tJOsuDP16kio85iA==} + engines: {node: ^18.18.0 || >=20.0.0} dependencies: - '@typescript-eslint/types': 7.2.0 - '@typescript-eslint/visitor-keys': 7.2.0 + '@typescript-eslint/types': 7.5.0 + '@typescript-eslint/visitor-keys': 7.5.0 dev: true - /@typescript-eslint/type-utils@7.2.0(eslint@8.57.0)(typescript@5.4.2): - resolution: {integrity: sha512-xHi51adBHo9O9330J8GQYQwrKBqbIPJGZZVQTHHmy200hvkLZFWJIFtAG/7IYTWUyun6DE6w5InDReePJYJlJA==} - engines: {node: ^16.0.0 || >=18.0.0} + /@typescript-eslint/type-utils@7.5.0(eslint@8.57.0)(typescript@5.4.4): + resolution: {integrity: sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 typescript: '*' @@ -899,55 +899,55 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.4.2) - '@typescript-eslint/utils': 7.2.0(eslint@8.57.0)(typescript@5.4.2) + '@typescript-eslint/typescript-estree': 7.5.0(typescript@5.4.4) + '@typescript-eslint/utils': 7.5.0(eslint@8.57.0)(typescript@5.4.4) debug: 4.3.4 eslint: 8.57.0 - ts-api-utils: 1.3.0(typescript@5.4.2) - typescript: 5.4.2 + ts-api-utils: 1.3.0(typescript@5.4.4) + typescript: 5.4.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types@7.2.0: - resolution: {integrity: sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==} - engines: {node: ^16.0.0 || >=18.0.0} + /@typescript-eslint/types@7.5.0: + resolution: {integrity: sha512-tv5B4IHeAdhR7uS4+bf8Ov3k793VEVHd45viRRkehIUZxm0WF82VPiLgHzA/Xl4TGPg1ZD49vfxBKFPecD5/mg==} + engines: {node: ^18.18.0 || >=20.0.0} dev: true - /@typescript-eslint/typescript-estree@7.2.0(typescript@5.4.2): - resolution: {integrity: sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==} - engines: {node: ^16.0.0 || >=18.0.0} + /@typescript-eslint/typescript-estree@7.5.0(typescript@5.4.4): + resolution: {integrity: sha512-YklQQfe0Rv2PZEueLTUffiQGKQneiIEKKnfIqPIOxgM9lKSZFCjT5Ad4VqRKj/U4+kQE3fa8YQpskViL7WjdPQ==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/types': 7.2.0 - '@typescript-eslint/visitor-keys': 7.2.0 + '@typescript-eslint/types': 7.5.0 + '@typescript-eslint/visitor-keys': 7.5.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 semver: 7.6.0 - ts-api-utils: 1.3.0(typescript@5.4.2) - typescript: 5.4.2 + ts-api-utils: 1.3.0(typescript@5.4.4) + typescript: 5.4.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@7.2.0(eslint@8.57.0)(typescript@5.4.2): - resolution: {integrity: sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==} - engines: {node: ^16.0.0 || >=18.0.0} + /@typescript-eslint/utils@7.5.0(eslint@8.57.0)(typescript@5.4.4): + resolution: {integrity: sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw==} + 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) '@types/json-schema': 7.0.15 '@types/semver': 7.5.8 - '@typescript-eslint/scope-manager': 7.2.0 - '@typescript-eslint/types': 7.2.0 - '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.4.2) + '@typescript-eslint/scope-manager': 7.5.0 + '@typescript-eslint/types': 7.5.0 + '@typescript-eslint/typescript-estree': 7.5.0(typescript@5.4.4) eslint: 8.57.0 semver: 7.6.0 transitivePeerDependencies: @@ -955,11 +955,11 @@ packages: - typescript dev: true - /@typescript-eslint/visitor-keys@7.2.0: - resolution: {integrity: sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==} - engines: {node: ^16.0.0 || >=18.0.0} + /@typescript-eslint/visitor-keys@7.5.0: + resolution: {integrity: sha512-mcuHM/QircmA6O7fy6nn2w/3ditQkj+SgtOc8DW3uQ10Yfj42amm2i+6F2K4YAOPNNTmE6iM1ynM6lrSwdendA==} + engines: {node: ^18.18.0 || >=20.0.0} dependencies: - '@typescript-eslint/types': 7.2.0 + '@typescript-eslint/types': 7.5.0 eslint-visitor-keys: 3.4.3 dev: true @@ -1265,7 +1265,7 @@ packages: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} dev: true - /create-jest@29.7.0(@types/node@20.11.27): + /create-jest@29.7.0(@types/node@20.12.4): resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -1274,7 +1274,7 @@ packages: chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.11.27) + jest-config: 29.7.0(@types/node@20.12.4) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -1906,7 +1906,7 @@ packages: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.27 + '@types/node': 20.12.4 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.1 @@ -1927,7 +1927,7 @@ packages: - supports-color dev: true - /jest-cli@29.7.0(@types/node@20.11.27): + /jest-cli@29.7.0(@types/node@20.12.4): resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -1941,10 +1941,10 @@ packages: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.11.27) + create-jest: 29.7.0(@types/node@20.12.4) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.11.27) + jest-config: 29.7.0(@types/node@20.12.4) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -1955,7 +1955,7 @@ packages: - ts-node dev: true - /jest-config@29.7.0(@types/node@20.11.27): + /jest-config@29.7.0(@types/node@20.12.4): resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -1970,7 +1970,7 @@ packages: '@babel/core': 7.23.9 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.27 + '@types/node': 20.12.4 babel-jest: 29.7.0(@babel/core@7.23.9) chalk: 4.1.2 ci-info: 3.9.0 @@ -2030,7 +2030,7 @@ packages: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.27 + '@types/node': 20.12.4 jest-mock: 29.7.0 jest-util: 29.7.0 dev: true @@ -2046,7 +2046,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 20.11.27 + '@types/node': 20.12.4 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -2097,7 +2097,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.27 + '@types/node': 20.12.4 jest-util: 29.7.0 dev: true @@ -2152,7 +2152,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.27 + '@types/node': 20.12.4 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -2183,7 +2183,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.27 + '@types/node': 20.12.4 chalk: 4.1.2 cjs-module-lexer: 1.2.3 collect-v8-coverage: 1.0.2 @@ -2235,7 +2235,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.27 + '@types/node': 20.12.4 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -2260,7 +2260,7 @@ packages: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.27 + '@types/node': 20.12.4 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -2272,13 +2272,13 @@ packages: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 20.11.27 + '@types/node': 20.12.4 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true - /jest@29.7.0(@types/node@20.11.27): + /jest@29.7.0(@types/node@20.12.4): resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -2291,7 +2291,7 @@ packages: '@jest/core': 29.7.0 '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.11.27) + jest-cli: 29.7.0(@types/node@20.12.4) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -2357,8 +2357,8 @@ packages: engines: {node: '>=6'} dev: true - /lemmy-js-client@0.19.4-alpha.13: - resolution: {integrity: sha512-ru1dCqPSfOJdsGq7am5J7P7f+/hpyHGhNbCEV/JAZP2U1lGHul32gLpBkilDnStDNdeq52scjKx+3WskRJFGFA==} + /lemmy-js-client@0.19.4-alpha.16: + resolution: {integrity: sha512-9BKCpZeH5+dDkSuYLVPvJnRGOSa3/jBUqYlQH3r1p8TyCCBrxstIC2I+h9dZZtOg4RmK7ShcuZdk9LSMe1ZMyw==} dev: true /leven@3.1.0: @@ -2890,16 +2890,16 @@ packages: is-number: 7.0.0 dev: true - /ts-api-utils@1.3.0(typescript@5.4.2): + /ts-api-utils@1.3.0(typescript@5.4.4): resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' dependencies: - typescript: 5.4.2 + typescript: 5.4.4 dev: true - /ts-jest@29.1.2(@babel/core@7.23.9)(jest@29.7.0)(typescript@5.4.2): + /ts-jest@29.1.2(@babel/core@7.23.9)(jest@29.7.0)(typescript@5.4.4): resolution: {integrity: sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==} engines: {node: ^16.10.0 || ^18.0.0 || >=20.0.0} hasBin: true @@ -2923,13 +2923,13 @@ packages: '@babel/core': 7.23.9 bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@20.11.27) + jest: 29.7.0(@types/node@20.12.4) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 semver: 7.5.4 - typescript: 5.4.2 + typescript: 5.4.4 yargs-parser: 21.1.1 dev: true @@ -2959,8 +2959,8 @@ packages: engines: {node: '>=10'} dev: true - /typescript@5.4.2: - resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==} + /typescript@5.4.4: + resolution: {integrity: sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==} engines: {node: '>=14.17'} hasBin: true dev: true diff --git a/api_tests/src/comment.spec.ts b/api_tests/src/comment.spec.ts index de714f687..fc547481c 100644 --- a/api_tests/src/comment.spec.ts +++ b/api_tests/src/comment.spec.ts @@ -53,9 +53,7 @@ beforeAll(async () => { } }); -afterAll(() => { - unfollows(); -}); +afterAll(unfollows); function assertCommentFederation( commentOne?: CommentView, diff --git a/api_tests/src/community.spec.ts b/api_tests/src/community.spec.ts index 02fac3d9a..aa96f563c 100644 --- a/api_tests/src/community.spec.ts +++ b/api_tests/src/community.spec.ts @@ -31,10 +31,12 @@ import { searchPostLocal, longDelay, editCommunity, + unfollows, } from "./shared"; import { EditCommunity, EditSite } from "lemmy-js-client"; beforeAll(setupLogins); +afterAll(unfollows); function assertCommunityFederation( communityOne?: CommunityView, diff --git a/api_tests/src/follow.spec.ts b/api_tests/src/follow.spec.ts index 276213eac..161c7f045 100644 --- a/api_tests/src/follow.spec.ts +++ b/api_tests/src/follow.spec.ts @@ -15,9 +15,7 @@ import { beforeAll(setupLogins); -afterAll(() => { - unfollows(); -}); +afterAll(unfollows); test("Follow local community", async () => { let user = await registerUser(beta, betaUrl); diff --git a/api_tests/src/image.spec.ts b/api_tests/src/image.spec.ts index 3a82b572d..055c498e0 100644 --- a/api_tests/src/image.spec.ts +++ b/api_tests/src/image.spec.ts @@ -15,7 +15,6 @@ import { createCommunity, createPost, deleteAllImages, - delta, epsilon, followCommunity, gamma, @@ -28,14 +27,15 @@ import { setupLogins, waitForPost, unfollows, + editPostThumbnail, + getPost, + waitUntil, } from "./shared"; const downloadFileSync = require("download-file-sync"); beforeAll(setupLogins); -afterAll(() => { - unfollows(); -}); +afterAll(unfollows); test("Upload image and delete it", async () => { // Before running this test, you need to delete all previous images in the DB @@ -252,3 +252,74 @@ test("No image proxying if setting is disabled", async () => { // Make sure the alt text got federated expect(post.post_view.post.alt_text).toBe(betaPost.post.alt_text); }); + +test("Make regular post, and give it a custom thumbnail", async () => { + const uploadForm1: UploadImage = { + image: Buffer.from("testRegular1"), + }; + const upload1 = await alphaImage.uploadImage(uploadForm1); + + const community = await createCommunity(alphaImage); + + // Use wikipedia since it has an opengraph image + const wikipediaUrl = "https://wikipedia.org/"; + + let post = await createPost( + alphaImage, + community.community_view.community.id, + wikipediaUrl, + ); + + // Wait for the metadata to get fetched, since this is backgrounded now + post = await waitUntil( + () => getPost(alphaImage, post.post_view.post.id), + p => p.post_view.post.thumbnail_url != undefined, + ); + expect(post.post_view.post.url).toBe(wikipediaUrl); + expect(post.post_view.post.thumbnail_url).toBeDefined(); + + // Edit the thumbnail + await editPostThumbnail(alphaImage, post.post_view.post, upload1.url!); + + post = await waitUntil( + () => getPost(alphaImage, post.post_view.post.id), + p => p.post_view.post.thumbnail_url == upload1.url, + ); + + // Make sure the thumbnail got edited. + expect(post.post_view.post.thumbnail_url).toBe(upload1.url); +}); + +test("Create an image post, and make sure a custom thumbnail doesnt overwrite it", async () => { + const uploadForm1: UploadImage = { + image: Buffer.from("test1"), + }; + const upload1 = await alphaImage.uploadImage(uploadForm1); + + const uploadForm2: UploadImage = { + image: Buffer.from("test2"), + }; + const upload2 = await alphaImage.uploadImage(uploadForm2); + + const community = await createCommunity(alphaImage); + + let post = await createPost( + alphaImage, + community.community_view.community.id, + upload1.url, + ); + expect(post.post_view.post.url).toBe(upload1.url); + + // Edit the post + await editPostThumbnail(alphaImage, post.post_view.post, upload2.url!); + + // Wait for the metadata to get fetched + post = await waitUntil( + () => getPost(alphaImage, post.post_view.post.id), + p => p.post_view.post.thumbnail_url == upload1.url, + ); + + // Make sure the new custom thumbnail is ignored, and doesn't overwrite the image post + expect(post.post_view.post.url).toBe(upload1.url); + expect(post.post_view.post.thumbnail_url).toBe(upload1.url); +}); diff --git a/api_tests/src/post.spec.ts b/api_tests/src/post.spec.ts index 75f965431..b2ab50222 100644 --- a/api_tests/src/post.spec.ts +++ b/api_tests/src/post.spec.ts @@ -51,9 +51,7 @@ beforeAll(async () => { await unfollows(); }); -afterAll(() => { - unfollows(); -}); +afterAll(unfollows); async function assertPostFederation(postOne: PostView, postTwo: PostView) { // Link metadata is generated in background task and may not be ready yet at this time, diff --git a/api_tests/src/private_message.spec.ts b/api_tests/src/private_message.spec.ts index 063ee05ee..8fd683ff0 100644 --- a/api_tests/src/private_message.spec.ts +++ b/api_tests/src/private_message.spec.ts @@ -21,9 +21,7 @@ beforeAll(async () => { recipient_id = 3; }); -afterAll(() => { - unfollows(); -}); +afterAll(unfollows); test("Create a private message", async () => { let pmRes = await createPrivateMessage(alpha, recipient_id); diff --git a/api_tests/src/shared.ts b/api_tests/src/shared.ts index 723b63887..e363fffa4 100644 --- a/api_tests/src/shared.ts +++ b/api_tests/src/shared.ts @@ -226,6 +226,18 @@ export async function editPost( return api.editPost(form); } +export async function editPostThumbnail( + api: LemmyHttp, + post: Post, + customThumbnail: string, +): Promise { + let form: EditPost = { + post_id: post.id, + custom_thumbnail: customThumbnail, + }; + return api.editPost(form); +} + export async function deletePost( api: LemmyHttp, deleted: boolean, diff --git a/api_tests/src/user.spec.ts b/api_tests/src/user.spec.ts index 5af054918..f44f3cc0a 100644 --- a/api_tests/src/user.spec.ts +++ b/api_tests/src/user.spec.ts @@ -20,11 +20,13 @@ import { getComments, fetchFunction, alphaImage, + unfollows, } from "./shared"; import { LemmyHttp, SaveUserSettings, UploadImage } from "lemmy-js-client"; import { GetPosts } from "lemmy-js-client/dist/types/GetPosts"; beforeAll(setupLogins); +afterAll(unfollows); let apShortname: string; diff --git a/crates/api_common/src/request.rs b/crates/api_common/src/request.rs index fdd29a254..912fbc67e 100644 --- a/crates/api_common/src/request.rs +++ b/crates/api_common/src/request.rs @@ -97,29 +97,46 @@ pub fn generate_post_link_metadata( context: Data, ) { spawn_try_task(async move { + // Decide if the thumbnail should be generated let allow_sensitive = local_site_opt_to_sensitive(&local_site); let page_is_sensitive = post.nsfw; let allow_generate_thumbnail = allow_sensitive || !page_is_sensitive; - let mut thumbnail_url = custom_thumbnail.or_else(|| post.thumbnail_url.map(Into::into)); - let do_generate_thumbnail = thumbnail_url.is_none() && allow_generate_thumbnail; + let do_generate_thumbnail = + allow_generate_thumbnail && custom_thumbnail.is_none() && post.thumbnail_url.is_none(); // Generate local thumbnail only if no thumbnail was federated and 'sensitive' attributes allow it. let metadata = fetch_link_metadata_opt( - post.url.map(Into::into).as_ref(), + post.url.as_ref().map(DbUrl::inner), do_generate_thumbnail, &context, ) .await; - if let Some(thumbnail_url_) = metadata.thumbnail { - thumbnail_url = Some(thumbnail_url_.into()); - } - let thumbnail_url = proxy_image_link_opt_apub(thumbnail_url, &context).await?; + + // If its an image post, it needs to overwrite the thumbnail, and take precedence + let image_url = if metadata + .content_type + .as_ref() + .is_some_and(|content_type| content_type.starts_with("image")) + { + post.url.map(Into::into) + } else { + None + }; + + // Build the thumbnail url based on either the post image url, custom thumbnail, metadata fetch, or existing thumbnail. + let thumbnail_url = image_url + .or(custom_thumbnail) + .or(metadata.thumbnail.map(Into::into)) + .or(post.thumbnail_url.map(Into::into)); + + // Proxy the image fetch if necessary + let proxied_thumbnail_url = proxy_image_link_opt_apub(thumbnail_url, &context).await?; let form = PostUpdateForm { embed_title: Some(metadata.opengraph_data.title), embed_description: Some(metadata.opengraph_data.description), embed_video_url: Some(metadata.opengraph_data.embed_video_url), - thumbnail_url: Some(thumbnail_url), + thumbnail_url: Some(proxied_thumbnail_url), url_content_type: Some(metadata.content_type), ..Default::default() }; diff --git a/scripts/upgrade_deps.sh b/scripts/upgrade_deps.sh index 0c4ae6f0f..b20e9f35c 100755 --- a/scripts/upgrade_deps.sh +++ b/scripts/upgrade_deps.sh @@ -6,9 +6,9 @@ pushd ../ cargo udeps --all-targets # Upgrade deps -cargo upgrade --workspace +cargo upgrade -# Run check -cargo check +# Run clippy +cargo clippy popd