From 8657cc61a7ea6cf024bdc440eed786d2f6127864 Mon Sep 17 00:00:00 2001 From: CI <project_7_bot_1bfaee5701aed20091a86249a967a6c1@noreply.firefish.dev> Date: Tue, 11 Jun 2024 12:14:22 +0000 Subject: [PATCH 01/16] chore(deps): update dependency @swc/core to v1.5.28 --- packages/backend/package.json | 2 +- packages/firefish-js/package.json | 2 +- pnpm-lock.yaml | 176 +++++++++++++++--------------- 3 files changed, 90 insertions(+), 90 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 85944e1158..abb315b15c 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -121,7 +121,7 @@ }, "devDependencies": { "@swc/cli": "0.3.12", - "@swc/core": "1.5.27", + "@swc/core": "1.5.28", "@types/adm-zip": "0.5.5", "@types/color-convert": "2.0.3", "@types/content-disposition": "0.5.8", diff --git a/packages/firefish-js/package.json b/packages/firefish-js/package.json index e93d232ca7..759d28c4a6 100644 --- a/packages/firefish-js/package.json +++ b/packages/firefish-js/package.json @@ -22,7 +22,7 @@ }, "devDependencies": { "@swc/cli": "0.3.12", - "@swc/core": "1.5.27", + "@swc/core": "1.5.28", "@swc/types": "0.1.8", "@types/jest": "29.5.12", "@types/node": "20.14.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 70e9bf2d3e..44cea2104b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -317,7 +317,7 @@ importers: version: 0.2.3 typeorm: specifier: 0.3.20 - version: 0.3.20(ioredis@5.4.1)(pg@8.12.0)(ts-node@10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) + version: 0.3.20(ioredis@5.4.1)(pg@8.12.0)(ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) ulid: specifier: 2.3.0 version: 2.3.0 @@ -337,10 +337,10 @@ importers: devDependencies: '@swc/cli': specifier: 0.3.12 - version: 0.3.12(@swc/core@1.5.27)(chokidar@3.6.0) + version: 0.3.12(@swc/core@1.5.28)(chokidar@3.6.0) '@swc/core': - specifier: 1.5.27 - version: 1.5.27 + specifier: 1.5.28 + version: 1.5.28 '@types/adm-zip': specifier: 0.5.5 version: 0.5.5 @@ -490,13 +490,13 @@ importers: version: 2.0.0 swc-loader: specifier: 0.2.6 - version: 0.2.6(@swc/core@1.5.27)(webpack@5.91.0(@swc/core@1.5.27)) + version: 0.2.6(@swc/core@1.5.28)(webpack@5.91.0(@swc/core@1.5.28)) ts-loader: specifier: 9.5.1 - version: 9.5.1(typescript@5.4.5)(webpack@5.91.0(@swc/core@1.5.27)) + version: 9.5.1(typescript@5.4.5)(webpack@5.91.0(@swc/core@1.5.28)) ts-node: specifier: 10.9.2 - version: 10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5) + version: 10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5) tsconfig-paths: specifier: 4.2.0 version: 4.2.0 @@ -508,7 +508,7 @@ importers: version: 5.4.5 webpack: specifier: 5.91.0 - version: 5.91.0(@swc/core@1.5.27) + version: 5.91.0(@swc/core@1.5.28) ws: specifier: 8.17.0 version: 8.17.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -774,10 +774,10 @@ importers: devDependencies: '@swc/cli': specifier: 0.3.12 - version: 0.3.12(@swc/core@1.5.27)(chokidar@3.6.0) + version: 0.3.12(@swc/core@1.5.28)(chokidar@3.6.0) '@swc/core': - specifier: 1.5.27 - version: 1.5.27 + specifier: 1.5.28 + version: 1.5.28 '@swc/types': specifier: 0.1.8 version: 0.1.8 @@ -789,7 +789,7 @@ importers: version: 20.14.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) + version: 29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) jest-fetch-mock: specifier: 3.0.3 version: 3.0.3 @@ -801,10 +801,10 @@ importers: version: 9.3.1 ts-jest: specifier: 29.1.4 - version: 29.1.4(@babel/core@7.24.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.7))(jest@29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)))(typescript@5.4.5) + version: 29.1.4(@babel/core@7.24.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.7))(jest@29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)))(typescript@5.4.5) ts-node: specifier: 10.9.2 - version: 10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5) + version: 10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5) tsd: specifier: 0.31.0 version: 0.31.0 @@ -2175,68 +2175,68 @@ packages: cpu: [arm64] os: [android] - '@swc/core-darwin-arm64@1.5.27': - resolution: {integrity: sha512-jyoygXBcUcwUya2BI7Uvl0jwcm4kd0RBDGGkWgcFAZmwucSuLT3EsbpWhOwlL3ACT4rpnRlvh+k8nJlq3+w2Aw==} + '@swc/core-darwin-arm64@1.5.28': + resolution: {integrity: sha512-sP6g63ybzIdOWNDbn51tyHN8EMt7Mb4RMeHQEsXB7wQfDvzhpWB+AbfK6Gs3Q8fwP/pmWIrWW9csKOc1K2Mmkg==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.5.27': - resolution: {integrity: sha512-eOC583D6b3MS9oODCcZUvAV7ajunjENAPVQL7aZaW+piERW+o4koZAiPlzFdMAUMj7UeVg+UN9sBBbTbJgruIA==} + '@swc/core-darwin-x64@1.5.28': + resolution: {integrity: sha512-Bd/agp/g7QocQG5AuorOzSC78t8OzeN+pCN/QvJj1CvPhvppjJw6e1vAbOR8vO2vvGi2pvtf3polrYQStJtSiA==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.5.27': - resolution: {integrity: sha512-bMvX0yF7WYzn1K+s0JWJhvyA3OeZHVrdjka8eZ4LSeuLfC0ggJefo+klyeuN2szn/LYP6/3oByyrWNY8RSHB4w==} + '@swc/core-linux-arm-gnueabihf@1.5.28': + resolution: {integrity: sha512-Wr3TwPGIveS9/OBWm0r9VAL8wkCR0zQn46J8K01uYCmVhUNK3Muxjs0vQBZaOrGu94mqbj9OXY+gB3W7aDvGdA==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.5.27': - resolution: {integrity: sha512-KlkOcSPxrCqZTm4XrT/LT1o9gmyM2T6bw/hL6IwTYRBJg+sej4rc9iSfVRFZBfNuG3EVkFQSXxik+0yVOXR93Q==} + '@swc/core-linux-arm64-gnu@1.5.28': + resolution: {integrity: sha512-8G1ZwVTuLgTAVTMPD+M97eU6WeiRIlGHwKZ5fiJHPBcz1xqIC7jQcEh7XBkobkYoU5OILotls3gzjRt8CMNyDQ==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-arm64-musl@1.5.27': - resolution: {integrity: sha512-EwdTt5qykxFXJu7kS+0X0Mp/IlwO8KJ6LVNak2+N8bt1J1q/nCdg1tRDOYQ1Z/MVa1Tm+lJ664Qs1y2NY2SDTw==} + '@swc/core-linux-arm64-musl@1.5.28': + resolution: {integrity: sha512-0Ajdzb5Fzvz+XUbN5ESeHAz9aHHSYiQcm+vmsDi0TtPHmsalfnqEPZmnK0zPALPJPLQP2dDo4hELeDg3/c3xgA==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-x64-gnu@1.5.27': - resolution: {integrity: sha512-RsBbxbiSNWLJ2jbAdITtv30J4eZw4O/JJ5zxYgWI54TdY7YrVsqIdzuX+ldximt+CYvO9irHm/mSr/IJY2YXrw==} + '@swc/core-linux-x64-gnu@1.5.28': + resolution: {integrity: sha512-ueQ9VejnQUM2Pt+vT0IAKoF4vYBWUP6n1KHGdILpoGe3LuafQrqu7RoyQ15C7/AYii7hAeNhTFdf6gLbg8cjFg==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-linux-x64-musl@1.5.27': - resolution: {integrity: sha512-XpRx0Kpy6JEi1WSMqUfR3k8hXLqNOkVqFcUfzvfQ4QNBX5Ek7ywh7WAxlPhCrFp+wAfNAqqUyRY1xZpLvRU51A==} + '@swc/core-linux-x64-musl@1.5.28': + resolution: {integrity: sha512-G5th8Mg0az8CbY4GQt9/m5hg2Y0kGIwvQBeVACuLQB6q2Y4txzdiTpjmFqUUhEvvl7Klyx1IHvNhfXs3zpt7PA==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-win32-arm64-msvc@1.5.27': - resolution: {integrity: sha512-pwSTUIokyIp+Ha1pur34qdYjxqL1QzhP/HM8anzsFs4yvV2LSI7c3qc4GWPNv2eQ9WiFXyo29uCEIRN6qig7wg==} + '@swc/core-win32-arm64-msvc@1.5.28': + resolution: {integrity: sha512-JezwCGavZ7CkNXx4yInI4kpb71L0zxzxA9BFlmnsGKEEjVQcKc3hFpmIzfFVs+eotlBUwDNb0+Yo9m6Cb7lllA==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.5.27': - resolution: {integrity: sha512-S0S6vqFscvmxPolwmpZvTRfTbYR+eGcyc0ge4x/+HcnBCm+m84rcGxmp3bBb1edNFaIV+X47BlGvvh85cJ4rkQ==} + '@swc/core-win32-ia32-msvc@1.5.28': + resolution: {integrity: sha512-q8tW5J4RkOkl7vYShnWS//VAb2Ngolfm9WOMaF2GRJUr2Y/Xeb/+cNjdsNOqea2BzW049D5vdP7XPmir3/zUZw==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.5.27': - resolution: {integrity: sha512-aem+BcNW42JPbvV6L3Jl3LLj6G80aYADzYenToYisy0Aop0XZAxL/0FbhV+xWORNFtIUKynNtaa1CK7w0UxehQ==} + '@swc/core-win32-x64-msvc@1.5.28': + resolution: {integrity: sha512-jap6EiB3wG1YE1hyhNr9KLPpH4PGm+5tVMfN0l7fgKtV0ikgpcEN/YF94tru+z5m2HovqYW009+Evq9dcVGmpg==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.5.27': - resolution: {integrity: sha512-HmSSCBoUSRDFAd8aEB+WILkCofIp1c2OU6ZJWu1aCt6pijwQSkA4y51CTBcdvyy/+zX1W3cic7alfdhmQxxeEQ==} + '@swc/core@1.5.28': + resolution: {integrity: sha512-muCdNIqOTURUgYeyyOLYE3ShL8SZO6dw6bhRm6dCvxWzCZOncPc5fB0kjcPXTML+9KJoHL7ks5xg+vsQK+v6ig==} engines: {node: '>=10'} peerDependencies: '@swc/helpers': '*' @@ -8962,7 +8962,7 @@ snapshots: - supports-color - ts-node - '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5))': + '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -8976,7 +8976,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) + jest-config: 29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -9425,10 +9425,10 @@ snapshots: '@sqltools/formatter@1.2.5': {} - '@swc/cli@0.3.12(@swc/core@1.5.27)(chokidar@3.6.0)': + '@swc/cli@0.3.12(@swc/core@1.5.28)(chokidar@3.6.0)': dependencies: '@mole-inc/bin-wrapper': 8.0.1 - '@swc/core': 1.5.27 + '@swc/core': 1.5.28 '@swc/counter': 0.1.3 commander: 8.3.0 fast-glob: 3.3.2 @@ -9445,51 +9445,51 @@ snapshots: '@swc/wasm': 1.2.130 optional: true - '@swc/core-darwin-arm64@1.5.27': + '@swc/core-darwin-arm64@1.5.28': optional: true - '@swc/core-darwin-x64@1.5.27': + '@swc/core-darwin-x64@1.5.28': optional: true - '@swc/core-linux-arm-gnueabihf@1.5.27': + '@swc/core-linux-arm-gnueabihf@1.5.28': optional: true - '@swc/core-linux-arm64-gnu@1.5.27': + '@swc/core-linux-arm64-gnu@1.5.28': optional: true - '@swc/core-linux-arm64-musl@1.5.27': + '@swc/core-linux-arm64-musl@1.5.28': optional: true - '@swc/core-linux-x64-gnu@1.5.27': + '@swc/core-linux-x64-gnu@1.5.28': optional: true - '@swc/core-linux-x64-musl@1.5.27': + '@swc/core-linux-x64-musl@1.5.28': optional: true - '@swc/core-win32-arm64-msvc@1.5.27': + '@swc/core-win32-arm64-msvc@1.5.28': optional: true - '@swc/core-win32-ia32-msvc@1.5.27': + '@swc/core-win32-ia32-msvc@1.5.28': optional: true - '@swc/core-win32-x64-msvc@1.5.27': + '@swc/core-win32-x64-msvc@1.5.28': optional: true - '@swc/core@1.5.27': + '@swc/core@1.5.28': dependencies: '@swc/counter': 0.1.3 '@swc/types': 0.1.8 optionalDependencies: - '@swc/core-darwin-arm64': 1.5.27 - '@swc/core-darwin-x64': 1.5.27 - '@swc/core-linux-arm-gnueabihf': 1.5.27 - '@swc/core-linux-arm64-gnu': 1.5.27 - '@swc/core-linux-arm64-musl': 1.5.27 - '@swc/core-linux-x64-gnu': 1.5.27 - '@swc/core-linux-x64-musl': 1.5.27 - '@swc/core-win32-arm64-msvc': 1.5.27 - '@swc/core-win32-ia32-msvc': 1.5.27 - '@swc/core-win32-x64-msvc': 1.5.27 + '@swc/core-darwin-arm64': 1.5.28 + '@swc/core-darwin-x64': 1.5.28 + '@swc/core-linux-arm-gnueabihf': 1.5.28 + '@swc/core-linux-arm64-gnu': 1.5.28 + '@swc/core-linux-arm64-musl': 1.5.28 + '@swc/core-linux-x64-gnu': 1.5.28 + '@swc/core-linux-x64-musl': 1.5.28 + '@swc/core-win32-arm64-msvc': 1.5.28 + '@swc/core-win32-ia32-msvc': 1.5.28 + '@swc/core-win32-x64-msvc': 1.5.28 '@swc/counter@0.1.3': {} @@ -11119,13 +11119,13 @@ snapshots: - supports-color - ts-node - create-jest@29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)): + create-jest@29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) + jest-config: 29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -13114,16 +13114,16 @@ snapshots: - supports-color - ts-node - jest-cli@29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)): + jest-cli@29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) + create-jest: 29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) + jest-config: 29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -13193,7 +13193,7 @@ snapshots: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)): + jest-config@29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)): dependencies: '@babel/core': 7.24.7 '@jest/test-sequencer': 29.7.0 @@ -13219,7 +13219,7 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 20.14.2 - ts-node: 10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5) + ts-node: 10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -13469,12 +13469,12 @@ snapshots: - supports-color - ts-node - jest@29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)): + jest@29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) + jest-cli: 29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -15468,11 +15468,11 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - swc-loader@0.2.6(@swc/core@1.5.27)(webpack@5.91.0(@swc/core@1.5.27)): + swc-loader@0.2.6(@swc/core@1.5.28)(webpack@5.91.0(@swc/core@1.5.28)): dependencies: - '@swc/core': 1.5.27 + '@swc/core': 1.5.28 '@swc/counter': 0.1.3 - webpack: 5.91.0(@swc/core@1.5.27) + webpack: 5.91.0(@swc/core@1.5.28) swiper@11.1.4: {} @@ -15513,16 +15513,16 @@ snapshots: fast-fifo: 1.3.2 streamx: 2.18.0 - terser-webpack-plugin@5.3.10(@swc/core@1.5.27)(webpack@5.91.0(@swc/core@1.5.27)): + terser-webpack-plugin@5.3.10(@swc/core@1.5.28)(webpack@5.91.0(@swc/core@1.5.28)): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.31.1 - webpack: 5.91.0(@swc/core@1.5.27) + webpack: 5.91.0(@swc/core@1.5.28) optionalDependencies: - '@swc/core': 1.5.27 + '@swc/core': 1.5.28 terser@5.31.1: dependencies: @@ -15647,11 +15647,11 @@ snapshots: '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.24.7) - ts-jest@29.1.4(@babel/core@7.24.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.7))(jest@29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)))(typescript@5.4.5): + ts-jest@29.1.4(@babel/core@7.24.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.7))(jest@29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)))(typescript@5.4.5): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) + jest: 29.7.0(@types/node@20.14.2)(ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -15665,7 +15665,7 @@ snapshots: '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.24.7) - ts-loader@9.5.1(typescript@5.4.5)(webpack@5.91.0(@swc/core@1.5.27)): + ts-loader@9.5.1(typescript@5.4.5)(webpack@5.91.0(@swc/core@1.5.28)): dependencies: chalk: 4.1.2 enhanced-resolve: 5.17.0 @@ -15673,9 +15673,9 @@ snapshots: semver: 7.6.2 source-map: 0.7.4 typescript: 5.4.5 - webpack: 5.91.0(@swc/core@1.5.27) + webpack: 5.91.0(@swc/core@1.5.28) - ts-node@10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5): + ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 @@ -15693,7 +15693,7 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: - '@swc/core': 1.5.27 + '@swc/core': 1.5.28 '@swc/wasm': 1.2.130 tsconfig-paths@3.15.0: @@ -15808,7 +15808,7 @@ snapshots: shiki: 0.14.7 typescript: 4.9.4 - typeorm@0.3.20(ioredis@5.4.1)(pg@8.12.0)(ts-node@10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)): + typeorm@0.3.20(ioredis@5.4.1)(pg@8.12.0)(ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5)): dependencies: '@sqltools/formatter': 1.2.5 app-root-path: 3.1.0 @@ -15828,7 +15828,7 @@ snapshots: optionalDependencies: ioredis: 5.4.1 pg: 8.12.0 - ts-node: 10.9.2(@swc/core@1.5.27)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5) + ts-node: 10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5) transitivePeerDependencies: - supports-color @@ -16048,7 +16048,7 @@ snapshots: webpack-sources@3.2.3: {} - webpack@5.91.0(@swc/core@1.5.27): + webpack@5.91.0(@swc/core@1.5.28): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.5 @@ -16071,7 +16071,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(@swc/core@1.5.27)(webpack@5.91.0(@swc/core@1.5.27)) + terser-webpack-plugin: 5.3.10(@swc/core@1.5.28)(webpack@5.91.0(@swc/core@1.5.28)) watchpack: 2.4.1 webpack-sources: 3.2.3 transitivePeerDependencies: From e10a18875152488300a1ed19bddd53100d28d5c9 Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Tue, 11 Jun 2024 23:23:00 +0900 Subject: [PATCH 02/16] refactor (backend): port publishNotesStream to backend-rs --- packages/backend-rs/index.d.ts | 1 + packages/backend-rs/index.js | 3 ++- packages/backend-rs/src/service/stream.rs | 1 + packages/backend-rs/src/service/stream/notes.rs | 13 +++++++++++++ packages/backend/src/services/note/create.ts | 9 +++------ packages/backend/src/services/stream.ts | 9 +++++---- 6 files changed, 25 insertions(+), 11 deletions(-) create mode 100644 packages/backend-rs/src/service/stream/notes.rs diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index 5f51bba686..e7d8bb0e76 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -1381,6 +1381,7 @@ export interface AbuseUserReportLike { comment: string } export function publishToModerationStream(moderatorId: string, report: AbuseUserReportLike): Promise<void> +export function publishToNotesStream(note: Note): Promise<void> export enum ChatEvent { Message = 0, Read = 1, diff --git a/packages/backend-rs/index.js b/packages/backend-rs/index.js index 6559eef30f..565ca43ce3 100644 --- a/packages/backend-rs/index.js +++ b/packages/backend-rs/index.js @@ -310,7 +310,7 @@ if (!nativeBinding) { throw new Error(`Failed to load native binding`) } -const { SECOND, MINUTE, HOUR, DAY, USER_ONLINE_THRESHOLD, USER_ACTIVE_THRESHOLD, FILE_TYPE_BROWSERSAFE, fetchMeta, updateMetaCache, metaToPugArgs, loadConfig, stringToAcct, acctToString, fetchNodeinfo, nodeinfo_2_1, nodeinfo_2_0, updateNodeinfoCache, Protocol, Inbound, Outbound, greet, initializeRustLogger, showServerInfo, isBlockedServer, isSilencedServer, isAllowedServer, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, getImageSizeFromUrl, isQuote, isSafeUrl, latestVersion, toMastodonId, fromMastodonId, getNoteSummary, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, removeOldAttestationChallenges, cpuInfo, cpuUsage, memoryUsage, storageUsage, AntennaSrc, DriveFileUsageHint, MutedNoteReason, NoteVisibility, NotificationType, PageVisibility, PollNoteVisibility, RelayStatus, UserEmojiModPerm, UserProfileFfvisibility, UserProfileMutingNotificationTypes, updateAntennasOnNewNote, updateAntennaCache, watchNote, unwatchNote, PushNotificationKind, sendPushNotification, publishToChannelStream, publishToChatStream, ChatIndexEvent, publishToChatIndexStream, publishToBroadcastStream, publishToGroupChatStream, publishToModerationStream, ChatEvent, getTimestamp, genId, genIdAt, generateSecureRandomString, generateUserToken } = nativeBinding +const { SECOND, MINUTE, HOUR, DAY, USER_ONLINE_THRESHOLD, USER_ACTIVE_THRESHOLD, FILE_TYPE_BROWSERSAFE, fetchMeta, updateMetaCache, metaToPugArgs, loadConfig, stringToAcct, acctToString, fetchNodeinfo, nodeinfo_2_1, nodeinfo_2_0, updateNodeinfoCache, Protocol, Inbound, Outbound, greet, initializeRustLogger, showServerInfo, isBlockedServer, isSilencedServer, isAllowedServer, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, getImageSizeFromUrl, isQuote, isSafeUrl, latestVersion, toMastodonId, fromMastodonId, getNoteSummary, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, removeOldAttestationChallenges, cpuInfo, cpuUsage, memoryUsage, storageUsage, AntennaSrc, DriveFileUsageHint, MutedNoteReason, NoteVisibility, NotificationType, PageVisibility, PollNoteVisibility, RelayStatus, UserEmojiModPerm, UserProfileFfvisibility, UserProfileMutingNotificationTypes, updateAntennasOnNewNote, updateAntennaCache, watchNote, unwatchNote, PushNotificationKind, sendPushNotification, publishToChannelStream, publishToChatStream, ChatIndexEvent, publishToChatIndexStream, publishToBroadcastStream, publishToGroupChatStream, publishToModerationStream, publishToNotesStream, ChatEvent, getTimestamp, genId, genIdAt, generateSecureRandomString, generateUserToken } = nativeBinding module.exports.SECOND = SECOND module.exports.MINUTE = MINUTE @@ -391,6 +391,7 @@ module.exports.publishToChatIndexStream = publishToChatIndexStream module.exports.publishToBroadcastStream = publishToBroadcastStream module.exports.publishToGroupChatStream = publishToGroupChatStream module.exports.publishToModerationStream = publishToModerationStream +module.exports.publishToNotesStream = publishToNotesStream module.exports.ChatEvent = ChatEvent module.exports.getTimestamp = getTimestamp module.exports.genId = genId diff --git a/packages/backend-rs/src/service/stream.rs b/packages/backend-rs/src/service/stream.rs index 4a72fc7ec0..baf3a278d3 100644 --- a/packages/backend-rs/src/service/stream.rs +++ b/packages/backend-rs/src/service/stream.rs @@ -5,6 +5,7 @@ pub mod chat_index; pub mod custom_emoji; pub mod group_chat; pub mod moderation; +pub mod notes; use crate::{ config::CONFIG, diff --git a/packages/backend-rs/src/service/stream/notes.rs b/packages/backend-rs/src/service/stream/notes.rs new file mode 100644 index 0000000000..6c2336e347 --- /dev/null +++ b/packages/backend-rs/src/service/stream/notes.rs @@ -0,0 +1,13 @@ +use crate::{ + model::entity::note, + service::stream::{publish_to_stream, Error, Stream}, +}; + +// for napi export +// https://github.com/napi-rs/napi-rs/issues/2060 +type Note = note::Model; + +#[crate::export(js_name = "publishToNotesStream")] +pub async fn publish(note: &Note) -> Result<(), Error> { + publish_to_stream(&Stream::Notes, None, Some(serde_json::to_string(note)?)).await +} diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index b37c007152..1dd2653845 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -1,9 +1,5 @@ import * as mfm from "mfm-js"; -import { - publishMainStream, - publishNotesStream, - publishNoteStream, -} from "@/services/stream.js"; +import { publishMainStream, publishNoteStream } from "@/services/stream.js"; import DeliverManager from "@/remote/activitypub/deliver-manager.js"; import renderNote from "@/remote/activitypub/renderer/note.js"; import renderCreate from "@/remote/activitypub/renderer/create.js"; @@ -49,6 +45,7 @@ import { genIdAt, isQuote, isSilencedServer, + publishToNotesStream, } from "backend-rs"; import { countSameRenotes } from "@/misc/count-same-renotes.js"; import { deliverToRelays, getCachedRelays } from "../relay.js"; @@ -661,7 +658,7 @@ export default async ( 30, ); } - publishNotesStream(noteToPublish); + publishToNotesStream(toRustObject(noteToPublish)); } } finally { await lock.release(); diff --git a/packages/backend/src/services/stream.ts b/packages/backend/src/services/stream.ts index 36914d4d41..c60d5ce974 100644 --- a/packages/backend/src/services/stream.ts +++ b/packages/backend/src/services/stream.ts @@ -193,9 +193,10 @@ class Publisher { // ); // }; - public publishNotesStream = (note: Note): void => { - this.publish("notesStream", null, note); - }; + /* ported to backend-rs */ + // public publishNotesStream = (note: Note): void => { + // this.publish("notesStream", null, note); + // }; /* ported to backend-rs */ // public publishAdminStream = <K extends keyof AdminStreamTypes>( @@ -221,7 +222,7 @@ export const publishUserEvent = publisher.publishUserEvent; export const publishMainStream = publisher.publishMainStream; export const publishDriveStream = publisher.publishDriveStream; export const publishNoteStream = publisher.publishNoteStream; -export const publishNotesStream = publisher.publishNotesStream; +// export const publishNotesStream = publisher.publishNotesStream; // export const publishChannelStream = publisher.publishChannelStream; export const publishUserListStream = publisher.publishUserListStream; // export const publishAntennaStream = publisher.publishAntennaStream; From 4e36d2216432f52d4364686935bbcf6788f40ea0 Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Tue, 11 Jun 2024 23:59:01 +0900 Subject: [PATCH 03/16] refactor (backend): port publishDriveStream to backend-rs --- packages/backend-rs/index.d.ts | 12 ++++ packages/backend-rs/index.js | 6 +- packages/backend-rs/src/service/stream.rs | 1 + .../backend-rs/src/service/stream/drive.rs | 58 +++++++++++++++++++ .../api/endpoints/drive/files/delete.ts | 4 +- .../api/endpoints/drive/files/update.ts | 5 +- .../api/endpoints/drive/folders/create.ts | 9 ++- .../api/endpoints/drive/folders/delete.ts | 4 +- .../api/endpoints/drive/folders/update.ts | 9 ++- .../backend/src/services/drive/add-file.ts | 19 ++++-- packages/backend/src/services/stream.ts | 27 ++++----- 11 files changed, 126 insertions(+), 28 deletions(-) create mode 100644 packages/backend-rs/src/service/stream/drive.rs diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index e7d8bb0e76..00381d8b4d 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -1373,6 +1373,18 @@ export interface PackedEmoji { height: number | null } export function publishToBroadcastStream(emoji: PackedEmoji): Promise<void> +export enum DriveFileEvent { + Create = 0, + Update = 1, + Delete = 2 +} +export enum DriveFolderEvent { + Create = 0, + Update = 1, + Delete = 2 +} +export function publishToDriveFileStream(userId: string, kind: DriveFileEvent, object: any): Promise<void> +export function publishToDriveFolderStream(userId: string, kind: DriveFolderEvent, object: any): Promise<void> export function publishToGroupChatStream(groupId: string, kind: ChatEvent, object: any): Promise<void> export interface AbuseUserReportLike { id: string diff --git a/packages/backend-rs/index.js b/packages/backend-rs/index.js index 565ca43ce3..b971a57ecc 100644 --- a/packages/backend-rs/index.js +++ b/packages/backend-rs/index.js @@ -310,7 +310,7 @@ if (!nativeBinding) { throw new Error(`Failed to load native binding`) } -const { SECOND, MINUTE, HOUR, DAY, USER_ONLINE_THRESHOLD, USER_ACTIVE_THRESHOLD, FILE_TYPE_BROWSERSAFE, fetchMeta, updateMetaCache, metaToPugArgs, loadConfig, stringToAcct, acctToString, fetchNodeinfo, nodeinfo_2_1, nodeinfo_2_0, updateNodeinfoCache, Protocol, Inbound, Outbound, greet, initializeRustLogger, showServerInfo, isBlockedServer, isSilencedServer, isAllowedServer, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, getImageSizeFromUrl, isQuote, isSafeUrl, latestVersion, toMastodonId, fromMastodonId, getNoteSummary, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, removeOldAttestationChallenges, cpuInfo, cpuUsage, memoryUsage, storageUsage, AntennaSrc, DriveFileUsageHint, MutedNoteReason, NoteVisibility, NotificationType, PageVisibility, PollNoteVisibility, RelayStatus, UserEmojiModPerm, UserProfileFfvisibility, UserProfileMutingNotificationTypes, updateAntennasOnNewNote, updateAntennaCache, watchNote, unwatchNote, PushNotificationKind, sendPushNotification, publishToChannelStream, publishToChatStream, ChatIndexEvent, publishToChatIndexStream, publishToBroadcastStream, publishToGroupChatStream, publishToModerationStream, publishToNotesStream, ChatEvent, getTimestamp, genId, genIdAt, generateSecureRandomString, generateUserToken } = nativeBinding +const { SECOND, MINUTE, HOUR, DAY, USER_ONLINE_THRESHOLD, USER_ACTIVE_THRESHOLD, FILE_TYPE_BROWSERSAFE, fetchMeta, updateMetaCache, metaToPugArgs, loadConfig, stringToAcct, acctToString, fetchNodeinfo, nodeinfo_2_1, nodeinfo_2_0, updateNodeinfoCache, Protocol, Inbound, Outbound, greet, initializeRustLogger, showServerInfo, isBlockedServer, isSilencedServer, isAllowedServer, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, getImageSizeFromUrl, isQuote, isSafeUrl, latestVersion, toMastodonId, fromMastodonId, getNoteSummary, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, removeOldAttestationChallenges, cpuInfo, cpuUsage, memoryUsage, storageUsage, AntennaSrc, DriveFileUsageHint, MutedNoteReason, NoteVisibility, NotificationType, PageVisibility, PollNoteVisibility, RelayStatus, UserEmojiModPerm, UserProfileFfvisibility, UserProfileMutingNotificationTypes, updateAntennasOnNewNote, updateAntennaCache, watchNote, unwatchNote, PushNotificationKind, sendPushNotification, publishToChannelStream, publishToChatStream, ChatIndexEvent, publishToChatIndexStream, publishToBroadcastStream, DriveFileEvent, DriveFolderEvent, publishToDriveFileStream, publishToDriveFolderStream, publishToGroupChatStream, publishToModerationStream, publishToNotesStream, ChatEvent, getTimestamp, genId, genIdAt, generateSecureRandomString, generateUserToken } = nativeBinding module.exports.SECOND = SECOND module.exports.MINUTE = MINUTE @@ -389,6 +389,10 @@ module.exports.publishToChatStream = publishToChatStream module.exports.ChatIndexEvent = ChatIndexEvent module.exports.publishToChatIndexStream = publishToChatIndexStream module.exports.publishToBroadcastStream = publishToBroadcastStream +module.exports.DriveFileEvent = DriveFileEvent +module.exports.DriveFolderEvent = DriveFolderEvent +module.exports.publishToDriveFileStream = publishToDriveFileStream +module.exports.publishToDriveFolderStream = publishToDriveFolderStream module.exports.publishToGroupChatStream = publishToGroupChatStream module.exports.publishToModerationStream = publishToModerationStream module.exports.publishToNotesStream = publishToNotesStream diff --git a/packages/backend-rs/src/service/stream.rs b/packages/backend-rs/src/service/stream.rs index baf3a278d3..36d7f841fe 100644 --- a/packages/backend-rs/src/service/stream.rs +++ b/packages/backend-rs/src/service/stream.rs @@ -3,6 +3,7 @@ pub mod channel; pub mod chat; pub mod chat_index; pub mod custom_emoji; +pub mod drive; pub mod group_chat; pub mod moderation; pub mod notes; diff --git a/packages/backend-rs/src/service/stream/drive.rs b/packages/backend-rs/src/service/stream/drive.rs new file mode 100644 index 0000000000..c3b49d0db3 --- /dev/null +++ b/packages/backend-rs/src/service/stream/drive.rs @@ -0,0 +1,58 @@ +use crate::service::stream::{publish_to_stream, Error, Stream}; + +#[crate::export] +pub enum DriveFileEvent { + Create, + Update, + Delete, +} + +#[crate::export] +pub enum DriveFolderEvent { + Create, + Update, + Delete, +} + +// We want to merge `kind` and `object` into a single enum and merge the 2 functions +// https://github.com/napi-rs/napi-rs/issues/2036 + +#[crate::export(js_name = "publishToDriveFileStream")] +pub async fn publish_file( + user_id: String, + kind: DriveFileEvent, + object: &serde_json::Value, // file (create, update) or file id (delete) +) -> Result<(), Error> { + let kind = match kind { + DriveFileEvent::Create => "fileCreated", + DriveFileEvent::Update => "fileUpdated", + DriveFileEvent::Delete => "fileDeleted", + }; + + publish_to_stream( + &Stream::Drive { user_id }, + Some(kind), + Some(serde_json::to_string(object)?), + ) + .await +} + +#[crate::export(js_name = "publishToDriveFolderStream")] +pub async fn publish_folder( + user_id: String, + kind: DriveFolderEvent, + object: &serde_json::Value, // folder (create, update) or folder id (delete) +) -> Result<(), Error> { + let kind = match kind { + DriveFolderEvent::Create => "folderCreated", + DriveFolderEvent::Update => "folderUpdated", + DriveFolderEvent::Delete => "folderDeleted", + }; + + publish_to_stream( + &Stream::Drive { user_id }, + Some(kind), + Some(serde_json::to_string(object)?), + ) + .await +} diff --git a/packages/backend/src/server/api/endpoints/drive/files/delete.ts b/packages/backend/src/server/api/endpoints/drive/files/delete.ts index 062b69b9c5..2b5b3bc7bd 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/delete.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/delete.ts @@ -1,5 +1,5 @@ import { deleteFile } from "@/services/drive/delete-file.js"; -import { publishDriveStream } from "@/services/stream.js"; +import { publishToDriveFileStream, DriveFileEvent } from "backend-rs"; import define from "@/server/api/define.js"; import { ApiError } from "@/server/api/error.js"; import { DriveFiles } from "@/models/index.js"; @@ -51,5 +51,5 @@ export default define(meta, paramDef, async (ps, user) => { await deleteFile(file); // Publish fileDeleted event - publishDriveStream(user.id, "fileDeleted", file.id); + publishToDriveFileStream(user.id, DriveFileEvent.Delete, file.id); }); diff --git a/packages/backend/src/server/api/endpoints/drive/files/update.ts b/packages/backend/src/server/api/endpoints/drive/files/update.ts index 4d9567a838..c82cffb4a6 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/update.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/update.ts @@ -1,8 +1,9 @@ -import { publishDriveStream } from "@/services/stream.js"; +import { publishToDriveFileStream, DriveFileEvent } from "backend-rs"; import { DriveFiles, DriveFolders } from "@/models/index.js"; import { config } from "@/config.js"; import define from "@/server/api/define.js"; import { ApiError } from "@/server/api/error.js"; +import { toRustObject } from "@/prelude/undefined-to-null.js"; export const meta = { tags: ["drive"], @@ -110,7 +111,7 @@ export default define(meta, paramDef, async (ps, user) => { const fileObj = await DriveFiles.pack(file, { self: true }); // Publish fileUpdated event - publishDriveStream(user.id, "fileUpdated", fileObj); + publishToDriveFileStream(user.id, DriveFileEvent.Update, toRustObject(file)); return fileObj; }); diff --git a/packages/backend/src/server/api/endpoints/drive/folders/create.ts b/packages/backend/src/server/api/endpoints/drive/folders/create.ts index 1d9ef1831f..8d8c8b37b4 100644 --- a/packages/backend/src/server/api/endpoints/drive/folders/create.ts +++ b/packages/backend/src/server/api/endpoints/drive/folders/create.ts @@ -1,8 +1,9 @@ -import { publishDriveStream } from "@/services/stream.js"; +import { publishToDriveFolderStream, DriveFolderEvent } from "backend-rs"; import define from "@/server/api/define.js"; import { ApiError } from "@/server/api/error.js"; import { DriveFolders } from "@/models/index.js"; import { genIdAt } from "backend-rs"; +import { toRustObject } from "@/prelude/undefined-to-null.js"; export const meta = { tags: ["drive"], @@ -64,7 +65,11 @@ export default define(meta, paramDef, async (ps, user) => { const folderObj = await DriveFolders.pack(folder); // Publish folderCreated event - publishDriveStream(user.id, "folderCreated", folderObj); + publishToDriveFolderStream( + user.id, + DriveFolderEvent.Create, + toRustObject(folder), + ); return folderObj; }); diff --git a/packages/backend/src/server/api/endpoints/drive/folders/delete.ts b/packages/backend/src/server/api/endpoints/drive/folders/delete.ts index 1954b43361..a5e80dee44 100644 --- a/packages/backend/src/server/api/endpoints/drive/folders/delete.ts +++ b/packages/backend/src/server/api/endpoints/drive/folders/delete.ts @@ -1,5 +1,5 @@ import define from "@/server/api/define.js"; -import { publishDriveStream } from "@/services/stream.js"; +import { publishToDriveFolderStream, DriveFolderEvent } from "backend-rs"; import { ApiError } from "@/server/api/error.js"; import { DriveFolders, DriveFiles } from "@/models/index.js"; @@ -56,5 +56,5 @@ export default define(meta, paramDef, async (ps, user) => { await DriveFolders.delete(folder.id); // Publish folderCreated event - publishDriveStream(user.id, "folderDeleted", folder.id); + publishToDriveFolderStream(user.id, DriveFolderEvent.Delete, folder.id); }); diff --git a/packages/backend/src/server/api/endpoints/drive/folders/update.ts b/packages/backend/src/server/api/endpoints/drive/folders/update.ts index 7b266548e5..0deb1ef8a8 100644 --- a/packages/backend/src/server/api/endpoints/drive/folders/update.ts +++ b/packages/backend/src/server/api/endpoints/drive/folders/update.ts @@ -1,7 +1,8 @@ -import { publishDriveStream } from "@/services/stream.js"; +import { publishToDriveFolderStream, DriveFolderEvent } from "backend-rs"; import define from "@/server/api/define.js"; import { ApiError } from "@/server/api/error.js"; import { DriveFolders } from "@/models/index.js"; +import { toRustObject } from "@/prelude/undefined-to-null.js"; export const meta = { tags: ["drive"], @@ -112,7 +113,11 @@ export default define(meta, paramDef, async (ps, user) => { const folderObj = await DriveFolders.pack(folder); // Publish folderUpdated event - publishDriveStream(user.id, "folderUpdated", folderObj); + publishToDriveFolderStream( + user.id, + DriveFolderEvent.Update, + toRustObject(folder), + ); return folderObj; }); diff --git a/packages/backend/src/services/drive/add-file.ts b/packages/backend/src/services/drive/add-file.ts index 1c5412ac2d..cf84ebd8f4 100644 --- a/packages/backend/src/services/drive/add-file.ts +++ b/packages/backend/src/services/drive/add-file.ts @@ -5,8 +5,14 @@ import { v4 as uuid } from "uuid"; import type S3 from "aws-sdk/clients/s3.js"; // TODO: migrate to SDK v3 import sharp from "sharp"; import { IsNull } from "typeorm"; -import { publishMainStream, publishDriveStream } from "@/services/stream.js"; -import { FILE_TYPE_BROWSERSAFE, fetchMeta, genId } from "backend-rs"; +import { publishMainStream } from "@/services/stream.js"; +import { + DriveFileEvent, + FILE_TYPE_BROWSERSAFE, + fetchMeta, + genId, + publishToDriveFileStream, +} from "backend-rs"; import { contentDisposition } from "@/misc/content-disposition.js"; import { getFileInfo } from "@/misc/get-file-info.js"; import { @@ -28,6 +34,7 @@ import { driveLogger } from "./logger.js"; import { GenerateVideoThumbnail } from "./generate-video-thumbnail.js"; import { deleteFile } from "./delete-file.js"; import { inspect } from "node:util"; +import { toRustObject } from "@/prelude/undefined-to-null.js"; const logger = driveLogger.createSubLogger("register", "yellow"); @@ -656,11 +663,15 @@ export async function addFile({ logger.info(`drive file has been created ${file.id}`); - if (user) { + if (user != null) { DriveFiles.pack(file, { self: true }).then((packedFile) => { // Publish driveFileCreated event publishMainStream(user.id, "driveFileCreated", packedFile); - publishDriveStream(user.id, "fileCreated", packedFile); + publishToDriveFileStream( + user.id, + DriveFileEvent.Create, + toRustObject(file), + ); }); } diff --git a/packages/backend/src/services/stream.ts b/packages/backend/src/services/stream.ts index c60d5ce974..f2f5cf76d9 100644 --- a/packages/backend/src/services/stream.ts +++ b/packages/backend/src/services/stream.ts @@ -12,7 +12,7 @@ import type { // AntennaStreamTypes, // BroadcastTypes, // ChannelStreamTypes, - DriveStreamTypes, + // DriveStreamTypes, // GroupMessagingStreamTypes, InternalStreamTypes, MainStreamTypes, @@ -88,17 +88,18 @@ class Publisher { ); }; - public publishDriveStream = <K extends keyof DriveStreamTypes>( - userId: User["id"], - type: K, - value?: DriveStreamTypes[K], - ): void => { - this.publish( - `driveStream:${userId}`, - type, - typeof value === "undefined" ? null : value, - ); - }; + /* ported to backend-rs */ + // public publishDriveStream = <K extends keyof DriveStreamTypes>( + // userId: User["id"], + // type: K, + // value?: DriveStreamTypes[K], + // ): void => { + // this.publish( + // `driveStream:${userId}`, + // type, + // typeof value === "undefined" ? null : value, + // ); + // }; public publishNoteStream = <K extends keyof NoteStreamTypes>( noteId: Note["id"], @@ -220,7 +221,7 @@ export const publishInternalEvent = publisher.publishInternalEvent; export const publishUserEvent = publisher.publishUserEvent; // export const publishBroadcastStream = publisher.publishBroadcastStream; export const publishMainStream = publisher.publishMainStream; -export const publishDriveStream = publisher.publishDriveStream; +// export const publishDriveStream = publisher.publishDriveStream; export const publishNoteStream = publisher.publishNoteStream; // export const publishNotesStream = publisher.publishNotesStream; // export const publishChannelStream = publisher.publishChannelStream; From 0cb4fbf6b4119de0b003e8c08ad16717cc2188df Mon Sep 17 00:00:00 2001 From: sup39 <dev@sup39.dev> Date: Wed, 12 Jun 2024 00:49:22 +0800 Subject: [PATCH 04/16] refactor: macro-rs -> macros + macros_impl Co-authored-by: naskya <m@naskya.net> --- .gitlab-ci.yml | 2 +- Cargo.lock | 18 +- Cargo.toml | 5 +- Dockerfile | 4 +- packages/backend-rs/Cargo.toml | 2 +- packages/backend-rs/src/config/server.rs | 2 +- packages/backend-rs/src/lib.rs | 2 +- packages/macro-rs/macros-impl/Cargo.toml | 11 + packages/macro-rs/macros-impl/src/lib.rs | 2 + packages/macro-rs/macros-impl/src/napi.rs | 451 ++++++++++++ packages/macro-rs/macros-impl/src/util/mod.rs | 3 + .../macro-rs/macros-impl/src/util/tester.rs | 121 ++++ packages/macro-rs/{ => macros}/Cargo.toml | 11 +- packages/macro-rs/macros/src/helper.rs | 88 +++ packages/macro-rs/macros/src/lib.rs | 81 +++ packages/macro-rs/src/lib.rs | 680 ------------------ 16 files changed, 780 insertions(+), 703 deletions(-) create mode 100644 packages/macro-rs/macros-impl/Cargo.toml create mode 100644 packages/macro-rs/macros-impl/src/lib.rs create mode 100644 packages/macro-rs/macros-impl/src/napi.rs create mode 100644 packages/macro-rs/macros-impl/src/util/mod.rs create mode 100644 packages/macro-rs/macros-impl/src/util/tester.rs rename packages/macro-rs/{ => macros}/Cargo.toml (52%) create mode 100644 packages/macro-rs/macros/src/helper.rs create mode 100644 packages/macro-rs/macros/src/lib.rs delete mode 100644 packages/macro-rs/src/lib.rs diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d68ae43810..7b12b3d7a5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -290,7 +290,7 @@ cargo:doc: - cp ci/cargo/config.toml /usr/local/cargo/config.toml script: - cargo doc --document-private-items - - printf "window.ALL_CRATES = ['backend_rs', 'macro_rs'];" > target/doc/crates.js + - printf 'window.ALL_CRATES = ["backend_rs", "macros", "macros_impl"];' > target/doc/crates.js - printf '<meta http-equiv="refresh" content="0; url=%s">' 'backend_rs' > target/doc/index.html - cd target/doc - npx --yes netlify-cli deploy --prod --site="${CARGO_DOC_SITE_ID}" --dir=. diff --git a/Cargo.lock b/Cargo.lock index 75db34e287..37ac78a5d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -210,7 +210,7 @@ dependencies = [ "idna", "image", "isahc", - "macro-rs", + "macros", "napi", "napi-build", "napi-derive", @@ -1718,18 +1718,24 @@ dependencies = [ ] [[package]] -name = "macro-rs" +name = "macros" version = "0.0.0" dependencies = [ - "convert_case", - "napi", - "napi-derive", + "macros-impl", "proc-macro2", "quote", "serde", "serde_json", +] + +[[package]] +name = "macros-impl" +version = "0.0.0" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", "syn 2.0.66", - "thiserror", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 0e3536a5b3..1fe4e70f51 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,10 @@ [workspace] -members = ["packages/backend-rs", "packages/macro-rs"] +members = ["packages/backend-rs", "packages/macro-rs/macros", "packages/macro-rs/macros-impl"] resolver = "2" [workspace.dependencies] -macro-rs = { path = "packages/macro-rs" } +macros = { path = "packages/macro-rs/macros" } +macros-impl = { path = "packages/macro-rs/macros-impl" } napi = { git = "https://github.com/napi-rs/napi-rs.git", rev = "ca2cd5c35a0c39ec4a94e93c6c5695b681046df2" } napi-derive = "2.16.5" diff --git a/Dockerfile b/Dockerfile index 5bad58b949..789f242070 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,8 +17,7 @@ COPY Cargo.toml Cargo.toml COPY Cargo.lock Cargo.lock COPY packages/backend-rs/Cargo.toml packages/backend-rs/Cargo.toml COPY packages/backend-rs/src/lib.rs packages/backend-rs/src/ -COPY packages/macro-rs/Cargo.toml packages/macro-rs/Cargo.toml -COPY packages/macro-rs/src/lib.rs packages/macro-rs/src/ +COPY packages/macro-rs packages/macro-rs/ # Configure pnpm, and install backend-rs dependencies RUN corepack enable && corepack prepare pnpm@latest --activate && pnpm --filter backend-rs install @@ -26,7 +25,6 @@ RUN cargo fetch --locked --manifest-path Cargo.toml # Copy in the rest of the rust files COPY packages/backend-rs packages/backend-rs/ -# COPY packages/macro-rs packages/macro-rs/ # Compile backend-rs RUN NODE_ENV='production' pnpm run --filter backend-rs build diff --git a/packages/backend-rs/Cargo.toml b/packages/backend-rs/Cargo.toml index 996a95bce4..790ad0f317 100644 --- a/packages/backend-rs/Cargo.toml +++ b/packages/backend-rs/Cargo.toml @@ -12,7 +12,7 @@ napi = ["dep:napi", "dep:napi-derive", "dep:napi-build"] crate-type = ["cdylib", "lib"] [dependencies] -macro-rs = { workspace = true } +macros = { workspace = true } napi = { workspace = true, optional = true, features = ["chrono_date", "napi4", "serde-json", "tokio_rt"] } napi-derive = { workspace = true, optional = true } diff --git a/packages/backend-rs/src/config/server.rs b/packages/backend-rs/src/config/server.rs index 5170b0617e..8991caec99 100644 --- a/packages/backend-rs/src/config/server.rs +++ b/packages/backend-rs/src/config/server.rs @@ -4,7 +4,7 @@ use once_cell::sync::Lazy; use serde::Deserialize; use std::{env, fs}; -pub const VERSION: &str = macro_rs::read_version_from_package_json!(); +pub const VERSION: &str = macros::read_version_from_package_json!(); #[derive(Deserialize)] #[serde(rename_all = "camelCase")] diff --git a/packages/backend-rs/src/lib.rs b/packages/backend-rs/src/lib.rs index 6a124de340..dbb3f734a1 100644 --- a/packages/backend-rs/src/lib.rs +++ b/packages/backend-rs/src/lib.rs @@ -1,4 +1,4 @@ -use macro_rs::{derive_clone_and_export, export, ts_export}; +use macros::{derive_clone_and_export, export, ts_export}; pub mod config; pub mod database; diff --git a/packages/macro-rs/macros-impl/Cargo.toml b/packages/macro-rs/macros-impl/Cargo.toml new file mode 100644 index 0000000000..8029372236 --- /dev/null +++ b/packages/macro-rs/macros-impl/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "macros-impl" +version = "0.0.0" +edition = "2021" +rust-version = "1.74" + +[dependencies] +convert_case = { workspace = true } +proc-macro2 = { workspace = true } +quote = { workspace = true } +syn = { workspace = true, features = ["clone-impls", "extra-traits", "full", "parsing", "printing"] } diff --git a/packages/macro-rs/macros-impl/src/lib.rs b/packages/macro-rs/macros-impl/src/lib.rs new file mode 100644 index 0000000000..8310f17148 --- /dev/null +++ b/packages/macro-rs/macros-impl/src/lib.rs @@ -0,0 +1,2 @@ +pub mod napi; +mod util; diff --git a/packages/macro-rs/macros-impl/src/napi.rs b/packages/macro-rs/macros-impl/src/napi.rs new file mode 100644 index 0000000000..11d9283d5b --- /dev/null +++ b/packages/macro-rs/macros-impl/src/napi.rs @@ -0,0 +1,451 @@ +//! Napi related macros + +use convert_case::{Case, Casing}; +use proc_macro2::{TokenStream, TokenTree}; +use quote::{quote, ToTokens}; + +/// Creates an extra wrapper function for [napi_derive](https://docs.rs/napi-derive/latest/napi_derive/). +/// +/// The macro is simply converted into `napi_derive::napi(...)` +/// if it is not applied to a function. +/// +/// The macro sets the following attributes by default if not specified: +/// - `use_nullable = true` (if `object` or `constructor` attribute is specified) +/// - `js_name` to the camelCase version of the original function name (for functions) +/// +/// The types of the function arguments is converted with following rules: +/// - `&str` and `&mut str` are converted to [`String`] +/// - `&[T]` and `&mut [T]` are converted to [`Vec<T>`] +/// - `&T` and `&mut T` are converted to `T` +/// - Other `T` remains `T` +/// +/// In addition, return type [`Result<T>`] and [`Result<T, E>`] are converted to [`napi::Result<T>`](https://docs.rs/napi/latest/napi/type.Result.html). +/// Note that `E` must implement [std::error::Error] trait, +/// and `crate::util::error_chain::format_error(error: &dyn std::error::Error) -> String` function must be present. +/// +/// # Examples +/// ## Applying the macro to a struct +/// ``` +/// # use macros_impl::napi::napi; +/// # macros_impl::macro_doctest!({ +/// #[macros::napi(object)] +/// struct Person { +/// id: i32, +/// name: String, +/// } +/// +/// # }, { +/// /******* the code above expands to *******/ +/// +/// #[napi_derive::napi(use_nullable = true, object)] +/// struct Person { +/// id: i32, +/// name: String, +/// } +/// # }); +/// ``` +/// +/// ## Function with explicitly specified `js_name` +/// ``` +/// # use macros_impl::napi::napi; +/// # macros_impl::macro_doctest!({ +/// #[macros::napi(js_name = "add1")] +/// pub fn add_one(x: i32) -> i32 { +/// x + 1 +/// } +/// +/// # }, { +/// /******* the code above expands to *******/ +/// +/// pub fn add_one(x: i32) -> i32 { +/// x + 1 +/// } +/// +/// #[napi_derive::napi(js_name = "add1")] +/// pub fn add_one_napi(x: i32) -> i32 { +/// add_one(x) +/// } +/// # }); +/// ``` +/// +/// ## Function with `i32` argument +/// ``` +/// # use macros_impl::napi::napi; +/// # macros_impl::macro_doctest!({ +/// #[macros::napi] +/// pub fn add_one(x: i32) -> i32 { +/// x + 1 +/// } +/// +/// # }, { +/// /******* the code above expands to *******/ +/// +/// pub fn add_one(x: i32) -> i32 { +/// x + 1 +/// } +/// #[napi_derive::napi(js_name = "addOne",)] +/// pub fn add_one_napi(x: i32) -> i32 { +/// add_one(x) +/// } +/// # }); +/// ``` +/// +/// ## Function with `&str` argument +/// ``` +/// # use macros_impl::napi::napi; +/// # macros_impl::macro_doctest!({ +/// #[macros::napi] +/// pub fn concatenate_string(str1: &str, str2: &str) -> String { +/// str1.to_owned() + str2 +/// } +/// +/// # }, { +/// /******* the code above expands to *******/ +/// +/// pub fn concatenate_string(str1: &str, str2: &str) -> String { +/// str1.to_owned() + str2 +/// } +/// +/// #[napi_derive::napi(js_name = "concatenateString",)] +/// pub fn concatenate_string_napi(str1: String, str2: String) -> String { +/// concatenate_string(&str1, &str2) +/// } +/// # }); +/// ``` +/// +/// ## Function with `&[String]` argument +/// ``` +/// # use macros_impl::napi::napi; +/// # macros_impl::macro_doctest!({ +/// #[macros::napi] +/// pub fn string_array_length(array: &[String]) -> u32 { +/// array.len() as u32 +/// } +/// +/// # }, { +/// /******* the code above expands to *******/ +/// +/// pub fn string_array_length(array: &[String]) -> u32 { +/// array.len() as u32 +/// } +/// +/// #[napi_derive::napi(js_name = "stringArrayLength",)] +/// pub fn string_array_length_napi(array: Vec<String>) -> u32 { +/// string_array_length(&array) +/// } +/// # }); +/// ``` +/// +/// ## Function with `Result<T, E>` return type +/// ``` +/// # quote::quote! { // prevent compiling the code +/// #[derive(thiserror::Error, Debug)] +/// pub enum IntegerDivisionError { +/// #[error("Divided by zero")] +/// DividedByZero, +/// #[error("Not divisible with remainder {0}")] +/// NotDivisible(i64), +/// } +/// # }; +/// +/// # use macros_impl::napi::napi; +/// # macros_impl::macro_doctest!({ +/// #[macros::napi] +/// pub fn integer_divide(dividend: i64, divisor: i64) -> Result<i64, IntegerDivisionError> { +/// match divisor { +/// 0 => Err(IntegerDivisionError::DividedByZero), +/// _ => match dividend % divisor { +/// 0 => Ok(dividend / divisor), +/// remainder => Err(IntegerDivisionError::NotDivisible(remainder)), +/// }, +/// } +/// } +/// # }, { +/// +/// /******* the function above expands to *******/ +/// +/// pub fn integer_divide(dividend: i64, divisor: i64) -> Result<i64, IntegerDivisionError> { +/// match divisor { +/// 0 => Err(IntegerDivisionError::DividedByZero), +/// _ => match dividend % divisor { +/// 0 => Ok(dividend / divisor), +/// remainder => Err(IntegerDivisionError::NotDivisible(remainder)), +/// }, +/// } +/// } +/// +/// #[napi_derive::napi(js_name = "integerDivide",)] +/// pub fn integer_divide_napi(dividend: i64, divisor: i64) -> napi::Result<i64> { +/// integer_divide(dividend, divisor) +/// .map_err(|err| napi::Error::from_reason(crate::util::error_chain::format_error(&err))) +/// } +/// # }); +/// ``` +/// +pub fn napi(macro_attr: TokenStream, item: TokenStream) -> TokenStream { + let macro_attr_tokens: Vec<TokenTree> = macro_attr.clone().into_iter().collect(); + // generated extra macro attr TokenStream (prepended before original input `macro_attr`) + let mut extra_macro_attr = TokenStream::new(); + + let item: syn::Item = + syn::parse2(item).expect("Failed to parse input TokenStream to syn::Item"); + + // handle non-functions + let syn::Item::Fn(item_fn) = item else { + // set `use_nullable = true` if `object` or `constructor` present but not `use_nullable` + if macro_attr_tokens.iter().any(|token| { + matches!(token, TokenTree::Ident(ident) if ident == "object" || ident == "constructor") + }) && !macro_attr_tokens.iter().any(|token| { + matches!(token, TokenTree::Ident(ident) if ident == "use_nullable") + }) { + quote! { use_nullable = true, }.to_tokens(&mut extra_macro_attr); + } + return quote! { + #[napi_derive::napi(#extra_macro_attr #macro_attr)] + #item + }; + }; + + // handle functions + let ident = &item_fn.sig.ident; + let item_fn_attrs = &item_fn.attrs; + let item_fn_vis = &item_fn.vis; + let mut item_fn_sig = item_fn.sig.clone(); + let mut function_call_modifiers = Vec::<TokenStream>::new(); + + // append "_napi" to function name + item_fn_sig.ident = syn::parse_str(&format!("{}_napi", &ident)).unwrap(); + + // append `.await` to function call in async function + if item_fn_sig.asyncness.is_some() { + function_call_modifiers.push(quote! { + .await + }); + } + + // convert return type `...::Result<T, ...>` to `napi::Result<T>` + if let syn::ReturnType::Type(_, ref mut return_type) = item_fn_sig.output { + if let Some(result_generic_type) = (|| { + let syn::Type::Path(return_type_path) = &**return_type else { + return None; + }; + // match a::b::c::Result + let last_segment = return_type_path.path.segments.last()?; + if last_segment.ident != "Result" { + return None; + }; + // extract <T, ...> from Result<T, ...> + let syn::PathArguments::AngleBracketed(generic_arguments) = &last_segment.arguments + else { + return None; + }; + // return T only + generic_arguments.args.first() + })() { + // modify return type + *return_type = syn::parse_quote! { + napi::Result<#result_generic_type> + }; + // add modifier to function call result + function_call_modifiers.push(quote! { + .map_err(|err| napi::Error::from_reason(crate::util::error_chain::format_error(&err))) + }); + } + }; + + // arguments in function call + let called_args: Vec<TokenStream> = item_fn_sig + .inputs + .iter_mut() + .map(|input| match input { + // self + syn::FnArg::Receiver(arg) => { + let mut tokens = TokenStream::new(); + if let Some((ampersand, lifetime)) = &arg.reference { + ampersand.to_tokens(&mut tokens); + lifetime.to_tokens(&mut tokens); + } + arg.mutability.to_tokens(&mut tokens); + arg.self_token.to_tokens(&mut tokens); + tokens + } + // typed argument + syn::FnArg::Typed(arg) => { + match &mut *arg.pat { + syn::Pat::Ident(ident) => { + let name = &ident.ident; + match &*arg.ty { + // reference type argument => move ref from sigature to function call + syn::Type::Reference(r) => { + // add reference anotations to arguments in function call + let mut tokens = TokenStream::new(); + r.and_token.to_tokens(&mut tokens); + if let Some(lifetime) = &r.lifetime { + lifetime.to_tokens(&mut tokens); + } + r.mutability.to_tokens(&mut tokens); + name.to_tokens(&mut tokens); + + // modify napi argument types in function sigature + // (1) add `mut` token to `&mut` type + ident.mutability = r.mutability; + // (2) remove reference + *arg.ty = syn::Type::Verbatim(match &*r.elem { + syn::Type::Slice(slice) => { + let ty = &*slice.elem; + quote! { Vec<#ty> } + } + _ => { + let elem_tokens = r.elem.to_token_stream(); + match elem_tokens.to_string().as_str() { + // &str => String + "str" => quote! { String }, + // &T => T + _ => elem_tokens, + } + } + }); + + // return arguments in function call + tokens + } + // o.w., return it as is + _ => quote! { #name }, + } + } + pat => panic!("Unexpected FnArg: {pat:#?}"), + } + } + }) + .collect(); + + // handle macro attr + // set js_name if not specified + if !macro_attr_tokens + .iter() + .any(|token| matches!(token, TokenTree::Ident(ident) if ident == "js_name")) + { + let js_name = ident.to_string().to_case(Case::Camel); + quote! { js_name = #js_name, }.to_tokens(&mut extra_macro_attr); + } + + quote! { + #item_fn + + #[napi_derive::napi(#extra_macro_attr #macro_attr)] + #(#item_fn_attrs)* + #item_fn_vis #item_fn_sig { + #ident(#(#called_args),*) + #(#function_call_modifiers)* + } + } +} + +crate::macro_unit_tests! { + mut_ref_argument: { + #[macros::napi] + pub fn append_string_and_clone( + base_str: &mut String, + appended_str: &str, + ) -> String { + base_str.push_str(appended_str); + base_str.to_owned() + } + } generates { + #[napi_derive::napi(js_name = "appendStringAndClone", )] + pub fn append_string_and_clone_napi( + mut base_str: String, + appended_str: String, + ) -> String { + append_string_and_clone(&mut base_str, &appended_str) + } + } + + result_return_type: { + #[macros::napi] + pub fn integer_divide( + dividend: i64, + divisor: i64, + ) -> Result<i64, IntegerDivisionError> { + match divisor { + 0 => Err(IntegerDivisionError::DividedByZero), + _ => match dividend % divisor { + 0 => Ok(dividend / divisor), + remainder => Err(IntegerDivisionError::NotDivisible(remainder)), + }, + } + } + } generates { + #[napi_derive::napi(js_name = "integerDivide", )] + pub fn integer_divide_napi( + dividend: i64, + divisor: i64, + ) -> napi::Result<i64> { + integer_divide(dividend, divisor) + .map_err(|err| napi::Error::from_reason(crate::util::error_chain::format_error(&err))) + } + } + + async_function: { + #[macros::napi] + pub async fn async_add_one(x: i32) -> i32 { + x + 1 + } + } generates { + #[napi_derive::napi(js_name = "asyncAddOne", )] + pub async fn async_add_one_napi(x: i32) -> i32 { + async_add_one(x) + .await + } + } + + slice_type: { + #[macros::napi] + pub fn string_array_length(array: &[String]) -> u32 { + array.len() as u32 + } + } generates { + #[napi_derive::napi(js_name = "stringArrayLength", )] + pub fn string_array_length_napi(array: Vec<String>) -> u32 { + string_array_length(&array) + } + } + + object_with_explicitly_set_use_nullable: { + #[macros::napi(object, use_nullable = false)] + struct Person { + id: i32, + name: Option<String>, + } + } becomes { + #[napi_derive::napi(object, use_nullable = false)] + struct Person { + id: i32, + name: Option<String>, + } + } + + macro_attr: { + #[macros::napi(ts_return_type = "number")] + pub fn add_one(x: i32) -> i32 { + x + 1 + } + } generates { + #[napi_derive::napi(js_name = "addOne", ts_return_type = "number")] + pub fn add_one_napi(x: i32) -> i32 { + add_one(x) + } + } + + explicitly_specified_js_name_and_other_macro_attr: { + #[macros::napi(ts_return_type = "number", js_name = "add1")] + pub fn add_one(x: i32) -> i32 { + x + 1 + } + } generates { + #[napi_derive::napi(ts_return_type = "number", js_name = "add1")] + pub fn add_one_napi(x: i32) -> i32 { + add_one(x) + } + } +} diff --git a/packages/macro-rs/macros-impl/src/util/mod.rs b/packages/macro-rs/macros-impl/src/util/mod.rs new file mode 100644 index 0000000000..83be476077 --- /dev/null +++ b/packages/macro-rs/macros-impl/src/util/mod.rs @@ -0,0 +1,3 @@ +//! Utilities for developing procedural macros + +mod tester; diff --git a/packages/macro-rs/macros-impl/src/util/tester.rs b/packages/macro-rs/macros-impl/src/util/tester.rs new file mode 100644 index 0000000000..2762f3d4fc --- /dev/null +++ b/packages/macro-rs/macros-impl/src/util/tester.rs @@ -0,0 +1,121 @@ +//! Macros for testing procedural macros + +/// Tests if the macro expands correctly. +/// +/// # Examples +/// ``` +/// use macros_impl::napi::napi; +/// +/// macros_impl::macro_doctest!({ +/// #[macros::napi(object)] +/// struct Person { +/// id: i32, +/// name: String, +/// } +/// }, { +/// #[napi_derive::napi(use_nullable = true, object)] +/// struct Person { +/// id: i32, +/// name: String, +/// } +/// }); +/// ``` +#[macro_export] +macro_rules! macro_doctest { + ({ + #[macros :: $macro_name:ident $(( $($attr:tt)* ))?] + $($item:tt)* + }, { + $($expanded:tt)* + }) => { + assert_eq!( + ::std::string::ToString::to_string( + &$macro_name( + ::quote::quote!($( $($attr)* )?), + ::quote::quote!($($item)*), + ) + ), + ::std::string::ToString::to_string( + &::quote::quote!($($expanded)*) + ) + ); + }; +} + +/// Creates unit tests for macros. +/// +/// # Examples +/// ``` +/// macros_impl::macro_unit_tests! { +/// add1_becomes: { +/// #[macros::napi(js_name = "add1")] +/// pub fn add_one(x: i32) -> i32 { +/// x + 1 +/// } +/// } becomes { // the code above should expand to the following code +/// pub fn add_one(x: i32) -> i32 { +/// x + 1 +/// } +/// +/// #[napi_derive::napi(js_name = "add1")] +/// pub fn add_one_napi(x: i32) -> i32 { +/// add_one(x) +/// } +/// } +/// +/// // this test case is equivalent to `add1_becomes` +/// add1_generates: { +/// #[macros::napi(js_name = "add1")] +/// pub fn add_one(x: i32) -> i32 { +/// x + 1 +/// } +/// } generates { // the code above should generate the following code +/// #[napi_derive::napi(js_name = "add1")] +/// pub fn add_one_napi(x: i32) -> i32 { +/// add_one(x) +/// } +/// } +/// } +/// ``` +#[macro_export] macro_rules! macro_unit_tests { + (@test $macro_name:ident($attr:ident, $item:ident) becomes $expanded:ident) => { + assert_eq!( + ::std::format!("{}", $macro_name($attr, $item)), + ::std::format!("{}", $expanded), + ); + }; + (@test $macro_name:ident($attr:ident, $item:ident) generates $expanded:ident) => { + let item_str = format!("{}", $item); + assert_eq!( + ::std::format!("{}", $macro_name($attr, $item)), + ::std::format!("{} {}", item_str, $expanded), + ); + }; + + ( + $( + $test_name:ident : { + #[macros :: $macro_name:ident $(( $($attr:tt)* ))?] + $($item:tt)* + } $op:tt { + $($expanded:tt)* + } + )* + ) => { + #[cfg(test)] + mod unit_test { + use super::*; + + $( + #[test] + fn $test_name() { + let attr = ::quote::quote!($( $($attr)* )?); + let item = ::quote::quote!($($item)*); + let expanded = ::quote::quote!($($expanded)*); + + $crate::macro_unit_tests!(@test $macro_name(attr, item) $op expanded); + } + )* + } + }; +} diff --git a/packages/macro-rs/Cargo.toml b/packages/macro-rs/macros/Cargo.toml similarity index 52% rename from packages/macro-rs/Cargo.toml rename to packages/macro-rs/macros/Cargo.toml index c805fcce36..6b10d7ac1d 100644 --- a/packages/macro-rs/Cargo.toml +++ b/packages/macro-rs/macros/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "macro-rs" +name = "macros" version = "0.0.0" edition = "2021" rust-version = "1.74" @@ -8,14 +8,9 @@ rust-version = "1.74" proc-macro = true [dependencies] -convert_case = { workspace = true } +macros-impl = { workspace = true } + proc-macro2 = { workspace = true } quote = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true, features = ["std"] } -syn = { workspace = true, features = ["extra-traits", "full"] } - -[dev-dependencies] -thiserror = { workspace = true } -napi = { workspace = true } -napi-derive = { workspace = true, features = ["noop"] } diff --git a/packages/macro-rs/macros/src/helper.rs b/packages/macro-rs/macros/src/helper.rs new file mode 100644 index 0000000000..a901ba27e9 --- /dev/null +++ b/packages/macro-rs/macros/src/helper.rs @@ -0,0 +1,88 @@ +//! Helper macros for developing procedural macros + +#[doc(hidden)] +pub(crate) use quote::quote; + +/// Defines wrapper #\[proc_macro_attribute]s. +/// +/// # Examples +/// ```ignore +/// define_wrapper_proc_macro_attributes! { +/// // expand `#[export(attr)]` to +/// // ``` +/// // #[cfg_attr(feature = "napi", macros::napi(#attr))] +/// // ``` +/// export(attr, item) { +/// #[cfg_attr(feature = "napi", macros::napi(#attr))] +/// #item +/// } +/// +/// // expand `#[ts_export(attr)]` to +/// // ``` +/// // #[cfg(feature = "napi")] +/// // #[macros::napi(#attr)] +/// // ``` +/// ts_export(attr, item) { +/// #[cfg(feature = "napi")] +/// #[macros::napi(#attr)] +/// #item +/// } +/// } +/// ``` +macro_rules! define_wrapper_proc_macro_attributes { + ( + $( + $(#[$meta:meta])* + $macro_name:ident ($arg_attr:ident, $arg_item:ident) { + $($body:tt)* + } + )* + ) => { + $( + $(#[$meta])* + #[proc_macro_attribute] + pub fn $macro_name( + attr: ::proc_macro::TokenStream, + item: ::proc_macro::TokenStream, + ) -> ::proc_macro::TokenStream { + let $arg_attr: ::proc_macro2::TokenStream = attr.into(); + let $arg_item: ::proc_macro2::TokenStream = item.into(); + ::quote::quote!($($body)*).into() + } + )* + } +} +pub(crate) use define_wrapper_proc_macro_attributes; + +/// Wraps and exports #\[proc_macro_attribute] implementation. +/// +/// # Examples +/// ```ignore +/// reexport_proc_macro_attributes! { +/// // wrap and export [macros_impl::napi::napi] as #[macros::napi] +/// macros_impl::napi::napi as napi +/// +/// // wrap and export [macros_impl::errors::errors] as #[macros::errors] +/// macros_impl::errors::errors as errors +/// } +/// ``` +macro_rules! reexport_proc_macro_attributes { + ( + $( + $(#[$meta:meta])* + $impl_path:path as $macro_name:ident + )* + ) => { + $( + $(#[$meta])* + #[proc_macro_attribute] + pub fn $macro_name( + attr: ::proc_macro::TokenStream, + item: ::proc_macro::TokenStream, + ) -> ::proc_macro::TokenStream { + $impl_path(attr.into(), item.into()).into() + } + )* + } +} +pub(crate) use reexport_proc_macro_attributes; diff --git a/packages/macro-rs/macros/src/lib.rs b/packages/macro-rs/macros/src/lib.rs new file mode 100644 index 0000000000..533f058a96 --- /dev/null +++ b/packages/macro-rs/macros/src/lib.rs @@ -0,0 +1,81 @@ +mod helper; +use helper::*; + +/// Reads the version field in the project root package.json at compile time. +/// +/// # Example +/// You can get a compile-time constant version number using this macro: +/// ``` +/// # use macros::read_version_from_package_json; +/// // VERSION == "YYYYMMDD" (or "YYYYMMDD-X") +/// const VERSION: &str = read_version_from_package_json!(); +/// ``` +#[proc_macro] +pub fn read_version_from_package_json(_item: proc_macro::TokenStream) -> proc_macro::TokenStream { + #[derive(serde::Deserialize)] + struct PackageJson { + version: String, + } + + let file = std::fs::File::open("package.json").expect("Failed to open package.json"); + let json: PackageJson = serde_json::from_reader(file).unwrap(); + let version = &json.version; + + quote!(#version).into() +} + +define_wrapper_proc_macro_attributes! { + /// Exports an enum to TypeScript, and derive [Clone]. + /// + /// You need this macro because [`napi_derive::napi`](https://docs.rs/napi-derive/latest/napi_derive/attr.napi.html) + /// automatically derives the [Clone] trait for enums and causes conflicts. + /// + /// This is a wrapper of [`napi_derive::napi`](https://docs.rs/napi-derive/latest/napi_derive/attr.napi.html) + /// that expands to + /// ```no_run + /// #[cfg_attr(not(feature = "napi"), derive(Clone))] + /// #[cfg_attr(feature = "napi", napi_derive::napi(attr))] + /// # enum E {} // to work around doc test compilation error + /// ``` + /// where `attr` is given attribute(s). + derive_clone_and_export(attr, item) { + #[cfg_attr(not(feature = "napi"), derive(Clone))] + #[cfg_attr(feature = "napi", napi_derive::napi(#attr))] + #item + } + + /// Exports a function, struct, enum, const, etc. to TypeScript. + /// + /// This is a wrapper of [macro@napi] that expands to + /// ```no_run + /// #[cfg_attr(feature = "napi", macros::napi(attr))] + /// # fn f() {} // to work around doc test compilation error + /// ``` + /// where `attr` is given attribute(s). See [macro@napi] for more details. + export(attr, item) { + #[cfg_attr(feature = "napi", macros::napi(#attr))] + #item + } + + /// Exports a function, struct, enum, const, etc. to TypeScript + /// and make it unable to use in Rust. + /// + /// This is a wrapper of [macro@napi] that expands to + /// ```no_run + /// #[cfg(feature = "napi")] + /// #[macros::napi(attr)] + /// # fn f() {} // to work around doc test compilation error + /// ``` + /// where `attr` is given attribute(s). See [macro@napi] for more details. + ts_export(attr, item) { + #[cfg(feature = "napi")] + #[macros::napi(#attr)] + #item + } +} + +reexport_proc_macro_attributes! { + /// Creates an extra wrapper function for [napi_derive](https://docs.rs/napi-derive/latest/napi_derive/). + /// See [macros_impl::napi::napi] for details. + macros_impl::napi::napi as napi +} diff --git a/packages/macro-rs/src/lib.rs b/packages/macro-rs/src/lib.rs deleted file mode 100644 index 65ad817e05..0000000000 --- a/packages/macro-rs/src/lib.rs +++ /dev/null @@ -1,680 +0,0 @@ -use convert_case::{Case, Casing}; -use proc_macro2::{TokenStream, TokenTree}; -use quote::{quote, ToTokens}; - -/// Read the version field in the project root package.json at compile time -/// -/// # Example -/// You can get a compile-time constant version number using this macro: -/// ``` -/// # use macro_rs::read_version_from_package_json; -/// // VERSION == "YYYYMMDD" (or "YYYYMMDD-X") -/// const VERSION: &str = read_version_from_package_json!(); -/// ``` -#[proc_macro] -pub fn read_version_from_package_json(_item: proc_macro::TokenStream) -> proc_macro::TokenStream { - #[derive(serde::Deserialize)] - struct PackageJson { - version: String, - } - - let file = std::fs::File::open("package.json").expect("Failed to open package.json"); - let json: PackageJson = serde_json::from_reader(file).unwrap(); - let version = &json.version; - - quote! { #version }.into() -} - -/// Export an enum to TypeScript, and derive [Clone]. -/// -/// You need this macro because [`napi_derive::napi`](https://docs.rs/napi-derive/latest/napi_derive/attr.napi.html) -/// automatically derives the [Clone] trait for enums and causes conflicts. -/// -/// This is a wrapper of [`napi_derive::napi`](https://docs.rs/napi-derive/latest/napi_derive/attr.napi.html) -/// that expands to -/// ```no_run -/// #[cfg_attr(not(feature = "napi"), derive(Clone))] -/// #[cfg_attr(feature = "napi", napi_derive::napi(attr))] -/// # enum E {} // to work around doc test compilation error -/// ``` -/// where `attr` is given attribute(s). -#[proc_macro_attribute] -pub fn derive_clone_and_export( - attr: proc_macro::TokenStream, - item: proc_macro::TokenStream, -) -> proc_macro::TokenStream { - let attr: TokenStream = attr.into(); - let item: TokenStream = item.into(); - - quote! { - #[cfg_attr(not(feature = "napi"), derive(Clone))] - #[cfg_attr(feature = "napi", napi_derive::napi(#attr))] - #item - } - .into() -} - -/// Export a function, struct, enum, const, etc. to TypeScript. -/// -/// This is a wrapper of [macro@napi] that expands to -/// ```no_run -/// #[cfg_attr(feature = "napi", macro_rs::napi(attr))] -/// # fn f() {} // to work around doc test compilation error -/// ``` -/// where `attr` is given attribute(s). See [macro@napi] for more details. -#[proc_macro_attribute] -pub fn export( - attr: proc_macro::TokenStream, - item: proc_macro::TokenStream, -) -> proc_macro::TokenStream { - let attr: TokenStream = attr.into(); - let item: TokenStream = item.into(); - - quote! { - #[cfg_attr(feature = "napi", macro_rs::napi(#attr))] - #item - } - .into() -} - -/// Export a function, struct, enum, const, etc. to TypeScript -/// and make it unable to use in Rust. -/// -/// This is a wrapper of [macro@napi] that expands to -/// ```no_run -/// #[cfg(feature = "napi")] -/// #[macro_rs::napi(attr)] -/// # fn f() {} // to work around doc test compilation error -/// ``` -/// where `attr` is given attribute(s). See [macro@napi] for more details. -#[proc_macro_attribute] -pub fn ts_export( - attr: proc_macro::TokenStream, - item: proc_macro::TokenStream, -) -> proc_macro::TokenStream { - let attr: TokenStream = attr.into(); - let item: TokenStream = item.into(); - - quote! { - #[cfg(feature = "napi")] - #[macro_rs::napi(#attr)] - #item - } - .into() -} - -/// Creates an extra wrapper function for [napi_derive](https://docs.rs/napi-derive/latest/napi_derive/). -/// -/// The macro is simply converted into `napi_derive::napi(...)` -/// if it is not applied to a function. -/// -/// The macro sets the following attributes by default if not specified: -/// - `use_nullable = true` (if `object` or `constructor` attribute is specified) -/// - `js_name` to the camelCase version of the original function name (for functions) -/// -/// The types of the function arguments is converted with following rules: -/// - `&str` and `&mut str` are converted to [`String`] -/// - `&[T]` and `&mut [T]` are converted to [`Vec<T>`] -/// - `&T` and `&mut T` are converted to `T` -/// - Other `T` remains `T` -/// -/// In addition, return type [`Result<T>`] and [`Result<T, E>`] are converted to [`napi::Result<T>`](https://docs.rs/napi/latest/napi/type.Result.html). -/// Note that `E` must implement [`std::string::ToString`] trait. -/// -/// # Examples -/// ## Applying the macro to a struct -/// ``` -/// #[macro_rs::napi(object)] -/// struct Person { -/// id: i32, -/// name: String, -/// } -/// ``` -/// simply becomes -/// ``` -/// #[napi_derive::napi(use_nullable = true, object)] -/// struct Person { -/// id: i32, -/// name: String, -/// } -/// ``` -/// -/// ## Function with explicitly specified `js_name` -/// ``` -/// #[macro_rs::napi(js_name = "add1")] -/// pub fn add_one(x: i32) -> i32 { -/// x + 1 -/// } -/// ``` -/// generates -/// ``` -/// # pub fn add_one(x: i32) -> i32 { -/// # x + 1 -/// # } -/// #[napi_derive::napi(js_name = "add1",)] -/// pub fn add_one_napi(x: i32) -> i32 { -/// add_one(x) -/// } -/// ``` -/// -/// ## Function with `i32` argument -/// ``` -/// #[macro_rs::napi] -/// pub fn add_one(x: i32) -> i32 { -/// x + 1 -/// } -/// ``` -/// generates -/// ``` -/// # pub fn add_one(x: i32) -> i32 { -/// # x + 1 -/// # } -/// #[napi_derive::napi(js_name = "addOne",)] -/// pub fn add_one_napi(x: i32) -> i32 { -/// add_one(x) -/// } -/// ``` -/// -/// ## Function with `&str` argument -/// ``` -/// #[macro_rs::napi] -/// pub fn concatenate_string(str1: &str, str2: &str) -> String { -/// str1.to_owned() + str2 -/// } -/// ``` -/// generates -/// ``` -/// # pub fn concatenate_string(str1: &str, str2: &str) -> String { -/// # str1.to_owned() + str2 -/// # } -/// #[napi_derive::napi(js_name = "concatenateString",)] -/// pub fn concatenate_string_napi(str1: String, str2: String) -> String { -/// concatenate_string(&str1, &str2) -/// } -/// ``` -/// -/// ## Function with `&[String]` argument -/// ``` -/// #[macro_rs::napi] -/// pub fn string_array_length(array: &[String]) -> u32 { -/// array.len() as u32 -/// } -/// ``` -/// generates -/// ``` -/// # pub fn string_array_length(array: &[String]) -> u32 { -/// # array.len() as u32 -/// # } -/// #[napi_derive::napi(js_name = "stringArrayLength",)] -/// pub fn string_array_length_napi(array: Vec<String>) -> u32 { -/// string_array_length(&array) -/// } -/// ``` -/// -/// ## Function with `Result<T, E>` return type -/// ```ignore -/// #[derive(thiserror::Error, Debug)] -/// pub enum IntegerDivisionError { -/// #[error("Divided by zero")] -/// DividedByZero, -/// #[error("Not divisible with remainder = {0}")] -/// NotDivisible(i64), -/// } -/// -/// #[macro_rs::napi] -/// pub fn integer_divide(dividend: i64, divisor: i64) -> Result<i64, IntegerDivisionError> { -/// match divisor { -/// 0 => Err(IntegerDivisionError::DividedByZero), -/// _ => match dividend % divisor { -/// 0 => Ok(dividend / divisor), -/// remainder => Err(IntegerDivisionError::NotDivisible(remainder)), -/// }, -/// } -/// } -/// ``` -/// generates -/// ```ignore -/// # #[derive(thiserror::Error, Debug)] -/// # pub enum IntegerDivisionError { -/// # #[error("Divided by zero")] -/// # DividedByZero, -/// # #[error("Not divisible with remainder = {0}")] -/// # NotDivisible(i64), -/// # } -/// # pub fn integer_divide(dividend: i64, divisor: i64) -> Result<i64, IntegerDivisionError> { -/// # match divisor { -/// # 0 => Err(IntegerDivisionError::DividedByZero), -/// # _ => match dividend % divisor { -/// # 0 => Ok(dividend / divisor), -/// # remainder => Err(IntegerDivisionError::NotDivisible(remainder)), -/// # }, -/// # } -/// # } -/// #[napi_derive::napi(js_name = "integerDivide",)] -/// pub fn integer_divide_napi(dividend: i64, divisor: i64) -> napi::Result<i64> { -/// integer_divide(dividend, divisor).map_err(|err| napi::Error::from_reason(crate::util::error_chain::format_error(&err))) -/// } -/// ``` -#[proc_macro_attribute] -pub fn napi( - attr: proc_macro::TokenStream, - item: proc_macro::TokenStream, -) -> proc_macro::TokenStream { - napi_impl(attr.into(), item.into()).into() -} - -fn napi_impl(macro_attr: TokenStream, item: TokenStream) -> TokenStream { - let macro_attr_tokens: Vec<TokenTree> = macro_attr.clone().into_iter().collect(); - // generated extra macro attr TokenStream (prepended before original input `macro_attr`) - let mut extra_macro_attr = TokenStream::new(); - - let item: syn::Item = - syn::parse2(item).expect("Failed to parse input TokenStream to syn::Item"); - - // handle non-functions - let syn::Item::Fn(item_fn) = item else { - // append `use_nullable = true` if `object` or `constructor` present but not `use_nullable` - if macro_attr_tokens.iter().any(|token| { - matches!(token, TokenTree::Ident(ident) if ident == "object" || ident == "constructor") - }) && !macro_attr_tokens.iter().any(|token| { - matches!(token, TokenTree::Ident(ident) if ident == "use_nullable") - }) { - quote! { use_nullable = true, }.to_tokens(&mut extra_macro_attr); - } - return quote! { - #[napi_derive::napi(#extra_macro_attr #macro_attr)] - #item - }; - }; - - // handle functions - let ident = &item_fn.sig.ident; - let item_fn_attrs = &item_fn.attrs; - let item_fn_vis = &item_fn.vis; - let mut item_fn_sig = item_fn.sig.clone(); - let mut function_call_modifiers = Vec::<TokenStream>::new(); - - // append "_napi" to function name - item_fn_sig.ident = syn::parse_str(&format!("{}_napi", &ident)).unwrap(); - - // append `.await` to function call in async function - if item_fn_sig.asyncness.is_some() { - function_call_modifiers.push(quote! { - .await - }); - } - - // convert return type `...::Result<T, ...>` to `napi::Result<T>` - if let syn::ReturnType::Type(_, ref mut return_type) = item_fn_sig.output { - if let Some(result_generic_type) = (|| { - let syn::Type::Path(return_type_path) = &**return_type else { - return None; - }; - // match a::b::c::Result - let last_segment = return_type_path.path.segments.last()?; - if last_segment.ident != "Result" { - return None; - }; - // extract <T, ...> from Result<T, ...> - let syn::PathArguments::AngleBracketed(generic_arguments) = &last_segment.arguments - else { - return None; - }; - // return T only - generic_arguments.args.first() - })() { - // modify return type - *return_type = syn::parse_quote! { - napi::Result<#result_generic_type> - }; - // add modifier to function call result - function_call_modifiers.push(quote! { - .map_err(|err| napi::Error::from_reason(crate::util::error_chain::format_error(&err))) - }); - } - }; - - // arguments in function call - let called_args: Vec<TokenStream> = item_fn_sig - .inputs - .iter_mut() - .map(|input| match input { - // self - syn::FnArg::Receiver(arg) => { - let mut tokens = TokenStream::new(); - if let Some((ampersand, lifetime)) = &arg.reference { - ampersand.to_tokens(&mut tokens); - lifetime.to_tokens(&mut tokens); - } - arg.mutability.to_tokens(&mut tokens); - arg.self_token.to_tokens(&mut tokens); - tokens - } - // typed argument - syn::FnArg::Typed(arg) => { - match &mut *arg.pat { - syn::Pat::Ident(ident) => { - let name = &ident.ident; - match &*arg.ty { - // reference type argument => move ref from sigature to function call - syn::Type::Reference(r) => { - // add reference anotations to arguments in function call - let mut tokens = TokenStream::new(); - r.and_token.to_tokens(&mut tokens); - if let Some(lifetime) = &r.lifetime { - lifetime.to_tokens(&mut tokens); - } - r.mutability.to_tokens(&mut tokens); - name.to_tokens(&mut tokens); - - // modify napi argument types in function sigature - // (1) add `mut` token to `&mut` type - ident.mutability = r.mutability; - // (2) remove reference - *arg.ty = syn::Type::Verbatim(match &*r.elem { - syn::Type::Slice(slice) => { - let ty = &*slice.elem; - quote! { Vec<#ty> } - } - _ => { - let elem_tokens = r.elem.to_token_stream(); - match elem_tokens.to_string().as_str() { - // &str => String - "str" => quote! { String }, - // &T => T - _ => elem_tokens, - } - } - }); - - // return arguments in function call - tokens - } - // o.w., return it as is - _ => quote! { #name }, - } - } - pat => panic!("Unexpected FnArg: {pat:#?}"), - } - } - }) - .collect(); - - // handle macro attr - // append js_name if not specified - if !macro_attr_tokens - .iter() - .any(|token| matches!(token, TokenTree::Ident(ident) if ident == "js_name")) - { - let js_name = ident.to_string().to_case(Case::Camel); - quote! { js_name = #js_name, }.to_tokens(&mut extra_macro_attr); - } - - quote! { - #item_fn - - #[napi_derive::napi(#extra_macro_attr #macro_attr)] - #(#item_fn_attrs)* - #item_fn_vis #item_fn_sig { - #ident(#(#called_args),*) - #(#function_call_modifiers)* - } - } -} - -#[cfg(test)] -mod tests { - use proc_macro2::TokenStream; - use quote::quote; - - macro_rules! test_macro_becomes { - ($source:expr, $generated:expr) => { - assert_eq!( - super::napi_impl(TokenStream::new(), $source).to_string(), - $generated.to_string(), - ) - }; - ($macro_attr:expr, $source:expr, $generated:expr) => { - assert_eq!( - super::napi_impl($macro_attr, $source).to_string(), - $generated.to_string(), - ) - }; - } - - macro_rules! test_macro_generates { - ($source:expr, $generated:expr) => { - assert_eq!( - super::napi_impl(TokenStream::new(), $source).to_string(), - format!("{} {}", $source, $generated), - ) - }; - ($macro_attr:expr, $source:expr, $generated:expr) => { - assert_eq!( - super::napi_impl($macro_attr, $source).to_string(), - format!("{} {}", $source, $generated), - ) - }; - } - - #[test] - fn primitive_argument() { - test_macro_generates!( - quote! { - pub fn add_one(x: i32) -> i32 { - x + 1 - } - }, - quote! { - #[napi_derive::napi(js_name = "addOne", )] - pub fn add_one_napi(x: i32) -> i32 { - add_one(x) - } - } - ); - } - - #[test] - fn str_ref_argument() { - test_macro_generates!( - quote! { - pub fn concatenate_string(str1: &str, str2: &str) -> String { - str1.to_owned() + str2 - } - }, - quote! { - #[napi_derive::napi(js_name = "concatenateString", )] - pub fn concatenate_string_napi(str1: String, str2: String) -> String { - concatenate_string(&str1, &str2) - } - } - ); - } - - #[test] - fn mut_ref_argument() { - test_macro_generates!( - quote! { - pub fn append_string_and_clone( - base_str: &mut String, - appended_str: &str, - ) -> String { - base_str.push_str(appended_str); - base_str.to_owned() - } - }, - quote! { - #[napi_derive::napi(js_name = "appendStringAndClone", )] - pub fn append_string_and_clone_napi( - mut base_str: String, - appended_str: String, - ) -> String { - append_string_and_clone(&mut base_str, &appended_str) - } - } - ); - } - - #[test] - fn result_return_type() { - test_macro_generates!( - quote! { - pub fn integer_divide( - dividend: i64, - divisor: i64, - ) -> Result<i64, IntegerDivisionError> { - match divisor { - 0 => Err(IntegerDivisionError::DividedByZero), - _ => match dividend % divisor { - 0 => Ok(dividend / divisor), - remainder => Err(IntegerDivisionError::NotDivisible(remainder)), - }, - } - } - }, - quote! { - #[napi_derive::napi(js_name = "integerDivide", )] - pub fn integer_divide_napi( - dividend: i64, - divisor: i64, - ) -> napi::Result<i64> { - integer_divide(dividend, divisor) - .map_err(|err| napi::Error::from_reason(crate::util::error_chain::format_error(&err))) - } - } - ); - } - - #[test] - fn async_function() { - test_macro_generates!( - quote! { - pub async fn async_add_one(x: i32) -> i32 { - x + 1 - } - }, - quote! { - #[napi_derive::napi(js_name = "asyncAddOne", )] - pub async fn async_add_one_napi(x: i32) -> i32 { - async_add_one(x) - .await - } - } - ) - } - - #[test] - fn slice_type() { - test_macro_generates!( - quote! { - pub fn string_array_length(array: &[String]) -> u32 { - array.len() as u32 - } - }, - quote! { - #[napi_derive::napi(js_name = "stringArrayLength", )] - pub fn string_array_length_napi(array: Vec<String>) -> u32 { - string_array_length(&array) - } - } - ) - } - - #[test] - fn object() { - test_macro_becomes!( - quote! { object }, - quote! { - struct Person { - id: i32, - name: Option<String>, - } - }, - quote! { - #[napi_derive::napi(use_nullable = true, object)] - struct Person { - id: i32, - name: Option<String>, - } - } - ) - } - - #[test] - fn object_with_explicitly_set_use_nullable() { - test_macro_becomes!( - quote! { object, use_nullable = false }, - quote! { - struct Person { - id: i32, - name: Option<String>, - } - }, - quote! { - #[napi_derive::napi(object, use_nullable = false)] - struct Person { - id: i32, - name: Option<String>, - } - } - ) - } - - #[test] - fn macro_attr() { - test_macro_generates!( - quote! { - ts_return_type = "number" - }, - quote! { - pub fn add_one(x: i32) -> i32 { - x + 1 - } - }, - quote! { - #[napi_derive::napi(js_name = "addOne", ts_return_type = "number")] - pub fn add_one_napi(x: i32) -> i32 { - add_one(x) - } - } - ) - } - - #[test] - fn explicitly_specified_js_name() { - test_macro_generates!( - quote! { - js_name = "add1" - }, - quote! { - pub fn add_one(x: i32) -> i32 { - x + 1 - } - }, - quote! { - #[napi_derive::napi(js_name = "add1")] - pub fn add_one_napi(x: i32) -> i32 { - add_one(x) - } - } - ) - } - - #[test] - fn explicitly_specified_js_name_and_other_macro_attr() { - test_macro_generates!( - quote! { ts_return_type = "number", js_name = "add1" }, - quote! { - pub fn add_one(x: i32) -> i32 { - x + 1 - } - }, - quote! { - #[napi_derive::napi(ts_return_type = "number", js_name = "add1")] - pub fn add_one_napi(x: i32) -> i32 { - add_one(x) - } - } - ) - } -} From d824cb319ac5fca3984a0f5a1de5e0a4b01e4b78 Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Wed, 12 Jun 2024 03:36:47 +0900 Subject: [PATCH 05/16] test (backend-rs): ignore some tests in Miri --- packages/backend-rs/src/database/cache.rs | 2 ++ packages/backend-rs/src/database/postgresql.rs | 4 ++++ packages/backend-rs/src/database/redis.rs | 4 ++++ packages/backend-rs/src/federation/nodeinfo/fetch.rs | 1 + packages/backend-rs/src/misc/get_image_size.rs | 2 ++ packages/backend-rs/src/misc/latest_version.rs | 1 + packages/backend-rs/src/misc/password.rs | 1 + 7 files changed, 15 insertions(+) diff --git a/packages/backend-rs/src/database/cache.rs b/packages/backend-rs/src/database/cache.rs index 1dcd81d9ec..2fe192cb1e 100644 --- a/packages/backend-rs/src/database/cache.rs +++ b/packages/backend-rs/src/database/cache.rs @@ -234,6 +234,7 @@ mod unit_test { use pretty_assertions::assert_eq; #[tokio::test] + #[cfg_attr(miri, ignore)] // can't call foreign function `getaddrinfo` on OS `linux` async fn set_get_expire() { #[derive(serde::Deserialize, serde::Serialize, PartialEq, Debug)] struct Data { @@ -278,6 +279,7 @@ mod unit_test { } #[tokio::test] + #[cfg_attr(miri, ignore)] // can't call foreign function `getaddrinfo` on OS `linux` async fn use_category() { let key_1 = "fire"; let key_2 = "fish"; diff --git a/packages/backend-rs/src/database/postgresql.rs b/packages/backend-rs/src/database/postgresql.rs index 3a95cd65fb..fbc7fe7018 100644 --- a/packages/backend-rs/src/database/postgresql.rs +++ b/packages/backend-rs/src/database/postgresql.rs @@ -42,6 +42,7 @@ mod unit_test { use sea_orm::{prelude::*, DbBackend, Statement}; #[tokio::test] + #[cfg_attr(miri, ignore)] // can't call foreign function `geteuid` on OS `linux` async fn connect_sequential() { get_conn().await.unwrap(); get_conn().await.unwrap(); @@ -51,12 +52,14 @@ mod unit_test { } #[tokio::test] + #[cfg_attr(miri, ignore)] // can't call foreign function `geteuid` on OS `linux` async fn connect_concurrent() { let [c1, c2, c3, c4, c5] = [get_conn(), get_conn(), get_conn(), get_conn(), get_conn()]; let _ = tokio::try_join!(c1, c2, c3, c4, c5).unwrap(); } #[tokio::test] + #[cfg_attr(miri, ignore)] // can't call foreign function `geteuid` on OS `linux` async fn connect_spawn() { let mut tasks = Vec::new(); @@ -69,6 +72,7 @@ mod unit_test { } #[tokio::test] + #[cfg_attr(miri, ignore)] // can't call foreign function `geteuid` on OS `linux` async fn access() { // DO NOT write any raw SQL query in the actual program // (with the exception of PGroonga features) diff --git a/packages/backend-rs/src/database/redis.rs b/packages/backend-rs/src/database/redis.rs index 3207e5cbbd..1b989da08b 100644 --- a/packages/backend-rs/src/database/redis.rs +++ b/packages/backend-rs/src/database/redis.rs @@ -119,6 +119,7 @@ mod unit_test { use redis::AsyncCommands; #[tokio::test] + #[cfg_attr(miri, ignore)] // can't call foreign function `getaddrinfo` on OS `linux` async fn connect_sequential() { get_conn().await.unwrap(); get_conn().await.unwrap(); @@ -128,12 +129,14 @@ mod unit_test { } #[tokio::test] + #[cfg_attr(miri, ignore)] // can't call foreign function `getaddrinfo` on OS `linux` async fn connect_concurrent() { let [c1, c2, c3, c4, c5] = [get_conn(), get_conn(), get_conn(), get_conn(), get_conn()]; let _ = tokio::try_join!(c1, c2, c3, c4, c5).unwrap(); } #[tokio::test] + #[cfg_attr(miri, ignore)] // can't call foreign function `getaddrinfo` on OS `linux` async fn connect_spawn() { let mut tasks = Vec::new(); @@ -146,6 +149,7 @@ mod unit_test { } #[tokio::test] + #[cfg_attr(miri, ignore)] // can't call foreign function `getaddrinfo` on OS `linux` async fn access() { let mut redis = get_conn().await.unwrap(); diff --git a/packages/backend-rs/src/federation/nodeinfo/fetch.rs b/packages/backend-rs/src/federation/nodeinfo/fetch.rs index 89a325e597..1004bc6f56 100644 --- a/packages/backend-rs/src/federation/nodeinfo/fetch.rs +++ b/packages/backend-rs/src/federation/nodeinfo/fetch.rs @@ -156,6 +156,7 @@ mod unit_test { } #[tokio::test] + #[cfg_attr(miri, ignore)] // can't call foreign function `curl_global_init` on OS `linux` async fn fetch_nodeinfo() { assert_eq!( super::fetch_nodeinfo("info.firefish.dev") diff --git a/packages/backend-rs/src/misc/get_image_size.rs b/packages/backend-rs/src/misc/get_image_size.rs index 31d5bb398f..58f9783fe0 100644 --- a/packages/backend-rs/src/misc/get_image_size.rs +++ b/packages/backend-rs/src/misc/get_image_size.rs @@ -134,6 +134,7 @@ mod unit_test { use pretty_assertions::assert_eq; #[tokio::test] + #[cfg_attr(miri, ignore)] // can't call foreign function `getaddrinfo` on OS `linux` async fn get_image_size_from_url() { let png_url_1 = "https://firefish.dev/firefish/firefish/-/raw/5891a90f71a8b9d5ea99c683ade7e485c685d642/packages/backend/assets/splash.png"; let png_url_2 = "https://firefish.dev/firefish/firefish/-/raw/5891a90f71a8b9d5ea99c683ade7e485c685d642/packages/backend/assets/notification-badges/at.png"; @@ -219,6 +220,7 @@ mod unit_test { } #[tokio::test] + #[cfg_attr(miri, ignore)] // can't call foreign function `getaddrinfo` on OS `linux` async fn too_many_attempts() { let url = "https://firefish.dev/firefish/firefish/-/raw/5891a90f71a8b9d5ea99c683ade7e485c685d642/packages/backend/assets/splash.png"; diff --git a/packages/backend-rs/src/misc/latest_version.rs b/packages/backend-rs/src/misc/latest_version.rs index ad1d6b2fc7..58f50d0b0b 100644 --- a/packages/backend-rs/src/misc/latest_version.rs +++ b/packages/backend-rs/src/misc/latest_version.rs @@ -99,6 +99,7 @@ mod unit_test { } #[tokio::test] + #[cfg_attr(miri, ignore)] // can't call foreign function `getaddrinfo` on OS `linux` async fn get_latest_version() { // delete caches in case you run this test multiple times cache::delete_one(cache::Category::FetchUrl, UPSTREAM_PACKAGE_JSON_URL) diff --git a/packages/backend-rs/src/misc/password.rs b/packages/backend-rs/src/misc/password.rs index b23b305e32..507313c778 100644 --- a/packages/backend-rs/src/misc/password.rs +++ b/packages/backend-rs/src/misc/password.rs @@ -51,6 +51,7 @@ mod unit_test { use super::{hash_password, is_old_password_algorithm}; #[test] + #[cfg_attr(miri, ignore)] // too slow fn verify_password() { let password = "omWc*%sD^fn7o2cXmc9e2QasBdrbRuhNB*gx!J5"; From 7db7fdaabedcb393f84ad84faff59c77d90f8bd3 Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Wed, 12 Jun 2024 03:37:01 +0900 Subject: [PATCH 06/16] chore: format --- packages/macro-rs/macros-impl/src/util/tester.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/macro-rs/macros-impl/src/util/tester.rs b/packages/macro-rs/macros-impl/src/util/tester.rs index 2762f3d4fc..717ed5fb19 100644 --- a/packages/macro-rs/macros-impl/src/util/tester.rs +++ b/packages/macro-rs/macros-impl/src/util/tester.rs @@ -77,7 +77,8 @@ macro_rules! macro_doctest { /// } /// } /// ``` -#[macro_export] macro_rules! macro_unit_tests { +#[macro_export] +macro_rules! macro_unit_tests { (@test $macro_name:ident($attr:ident, $item:ident) becomes $expanded:ident) => { assert_eq!( ::std::format!("{}", $macro_name($attr, $item)), From 9502289d8997949c127bfa168d1554f3d76662f4 Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Wed, 12 Jun 2024 03:38:31 +0900 Subject: [PATCH 07/16] chore (backend-rs): remove crate-level `use`s --- packages/backend-rs/src/config/constant.rs | 14 +++++----- packages/backend-rs/src/config/meta.rs | 8 +++--- packages/backend-rs/src/config/server.rs | 28 +++++++++---------- packages/backend-rs/src/federation/acct.rs | 6 ++-- .../src/federation/nodeinfo/fetch.rs | 2 +- .../src/federation/nodeinfo/generate.rs | 6 ++-- .../src/federation/nodeinfo/schema.rs | 16 +++++------ packages/backend-rs/src/init/greet.rs | 2 +- packages/backend-rs/src/init/log.rs | 2 +- packages/backend-rs/src/init/system_info.rs | 2 +- packages/backend-rs/src/lib.rs | 2 -- .../backend-rs/src/misc/check_server_block.rs | 6 ++-- .../backend-rs/src/misc/check_word_mute.rs | 4 +-- packages/backend-rs/src/misc/convert_host.rs | 10 +++---- packages/backend-rs/src/misc/emoji.rs | 2 +- packages/backend-rs/src/misc/escape_sql.rs | 4 +-- .../src/misc/format_milliseconds.rs | 2 +- .../backend-rs/src/misc/get_image_size.rs | 4 +-- packages/backend-rs/src/misc/is_quote.rs | 2 +- packages/backend-rs/src/misc/is_safe_url.rs | 2 +- .../backend-rs/src/misc/latest_version.rs | 2 +- packages/backend-rs/src/misc/mastodon_id.rs | 4 +-- .../backend-rs/src/misc/note/summarize.rs | 2 +- packages/backend-rs/src/misc/nyaify.rs | 2 +- packages/backend-rs/src/misc/password.rs | 6 ++-- packages/backend-rs/src/misc/reaction.rs | 8 +++--- .../misc/remove_old_attestation_challenges.rs | 2 +- packages/backend-rs/src/misc/system_info.rs | 14 +++++----- .../src/service/antenna/process_new_note.rs | 2 +- .../backend-rs/src/service/antenna/update.rs | 2 +- packages/backend-rs/src/service/note/watch.rs | 4 +-- .../src/service/push_notification.rs | 4 +-- packages/backend-rs/src/service/stream.rs | 2 +- .../backend-rs/src/service/stream/channel.rs | 2 +- .../backend-rs/src/service/stream/chat.rs | 2 +- .../src/service/stream/chat_index.rs | 4 +-- .../src/service/stream/custom_emoji.rs | 4 +-- .../backend-rs/src/service/stream/drive.rs | 8 +++--- .../src/service/stream/group_chat.rs | 2 +- .../src/service/stream/moderation.rs | 4 +-- .../backend-rs/src/service/stream/notes.rs | 2 +- packages/backend-rs/src/util/id.rs | 6 ++-- packages/backend-rs/src/util/random.rs | 4 +-- 43 files changed, 107 insertions(+), 109 deletions(-) diff --git a/packages/backend-rs/src/config/constant.rs b/packages/backend-rs/src/config/constant.rs index f2340893cd..7e6b50fa52 100644 --- a/packages/backend-rs/src/config/constant.rs +++ b/packages/backend-rs/src/config/constant.rs @@ -1,17 +1,17 @@ //! This module is used in the TypeScript backend only. -#[crate::ts_export] +#[macros::ts_export] pub const SECOND: i32 = 1000; -#[crate::ts_export] +#[macros::ts_export] pub const MINUTE: i32 = 60 * SECOND; -#[crate::ts_export] +#[macros::ts_export] pub const HOUR: i32 = 60 * MINUTE; -#[crate::ts_export] +#[macros::ts_export] pub const DAY: i32 = 24 * HOUR; -#[crate::ts_export] +#[macros::ts_export] pub const USER_ONLINE_THRESHOLD: i32 = 10 * MINUTE; -#[crate::ts_export] +#[macros::ts_export] pub const USER_ACTIVE_THRESHOLD: i32 = 3 * DAY; /// List of file types allowed to be viewed directly in the browser @@ -21,7 +21,7 @@ pub const USER_ACTIVE_THRESHOLD: i32 = 3 * DAY; /// * <https://github.com/sindresorhus/file-type/blob/main/supported.js> /// * <https://github.com/sindresorhus/file-type/blob/main/core.js> /// * <https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Containers> -#[crate::ts_export] +#[macros::ts_export] pub const FILE_TYPE_BROWSERSAFE: [&str; 41] = [ // Images "image/png", diff --git a/packages/backend-rs/src/config/meta.rs b/packages/backend-rs/src/config/meta.rs index cedb6cf0ad..969d9d35f5 100644 --- a/packages/backend-rs/src/config/meta.rs +++ b/packages/backend-rs/src/config/meta.rs @@ -11,12 +11,12 @@ fn set_cache(meta: &Meta) { let _ = CACHE.lock().map(|mut cache| *cache = Some(meta.clone())); } -#[crate::export(js_name = "fetchMeta")] +#[macros::export(js_name = "fetchMeta")] pub async fn local_server_info() -> Result<Meta, DbErr> { local_server_info_impl(true).await } -#[crate::export(js_name = "updateMetaCache")] +#[macros::export(js_name = "updateMetaCache")] pub async fn update() -> Result<(), DbErr> { local_server_info_impl(false).await?; Ok(()) @@ -49,7 +49,7 @@ async fn local_server_info_impl(use_cache: bool) -> Result<Meta, DbErr> { Ok(meta) } -#[crate::export(object)] +#[macros::export(object)] pub struct PugArgs { pub img: Option<String>, pub title: String, @@ -62,7 +62,7 @@ pub struct PugArgs { pub private_mode: Option<bool>, } -#[crate::ts_export] +#[macros::ts_export] pub fn meta_to_pug_args(meta: Meta) -> PugArgs { use rand::prelude::*; let mut rng = rand::thread_rng(); diff --git a/packages/backend-rs/src/config/server.rs b/packages/backend-rs/src/config/server.rs index 8991caec99..81f2baedb0 100644 --- a/packages/backend-rs/src/config/server.rs +++ b/packages/backend-rs/src/config/server.rs @@ -8,7 +8,7 @@ pub const VERSION: &str = macros::read_version_from_package_json!(); #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -#[crate::export(object, use_nullable = false)] +#[macros::export(object, use_nullable = false)] struct ServerConfig { pub url: String, pub port: u16, @@ -73,7 +73,7 @@ struct ServerConfig { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -#[crate::export(object, use_nullable = false)] +#[macros::export(object, use_nullable = false)] pub struct DbConfig { pub host: String, pub port: u16, @@ -86,7 +86,7 @@ pub struct DbConfig { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -#[crate::export(object, use_nullable = false)] +#[macros::export(object, use_nullable = false)] pub struct RedisConfig { pub host: String, pub port: u16, @@ -101,13 +101,13 @@ pub struct RedisConfig { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -#[crate::export(object, use_nullable = false)] +#[macros::export(object, use_nullable = false)] pub struct TlsConfig { pub host: String, pub reject_unauthorized: bool, } -#[crate::export(object, use_nullable = false)] +#[macros::export(object, use_nullable = false)] pub struct WorkerConfig { pub web: u32, pub queue: u32, @@ -115,7 +115,7 @@ pub struct WorkerConfig { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -#[crate::export(object, use_nullable = false)] +#[macros::export(object, use_nullable = false)] pub struct WorkerConfigInternal { pub web: Option<u32>, pub queue: Option<u32>, @@ -123,7 +123,7 @@ pub struct WorkerConfigInternal { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -#[crate::export(object, use_nullable = false)] +#[macros::export(object, use_nullable = false)] pub struct IdConfig { pub length: Option<u8>, pub fingerprint: Option<String>, @@ -131,7 +131,7 @@ pub struct IdConfig { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -#[crate::export(object, use_nullable = false)] +#[macros::export(object, use_nullable = false)] pub struct SysLogConfig { pub host: String, pub port: u16, @@ -139,7 +139,7 @@ pub struct SysLogConfig { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -#[crate::export(object, use_nullable = false)] +#[macros::export(object, use_nullable = false)] pub struct DeepLConfig { pub managed: Option<bool>, pub auth_key: Option<String>, @@ -148,7 +148,7 @@ pub struct DeepLConfig { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -#[crate::export(object, use_nullable = false)] +#[macros::export(object, use_nullable = false)] pub struct LibreTranslateConfig { pub managed: Option<bool>, pub api_url: Option<String>, @@ -157,7 +157,7 @@ pub struct LibreTranslateConfig { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -#[crate::export(object, use_nullable = false)] +#[macros::export(object, use_nullable = false)] pub struct EmailConfig { pub managed: Option<bool>, pub address: Option<String>, @@ -170,7 +170,7 @@ pub struct EmailConfig { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -#[crate::export(object, use_nullable = false)] +#[macros::export(object, use_nullable = false)] pub struct ObjectStorageConfig { pub managed: Option<bool>, pub base_url: Option<String>, @@ -186,7 +186,7 @@ pub struct ObjectStorageConfig { pub s3_force_path_style: Option<bool>, } -#[crate::export(object, use_nullable = false)] +#[macros::export(object, use_nullable = false)] pub struct Config { // ServerConfig (from default.yml) pub url: String, @@ -263,7 +263,7 @@ fn read_config_file() -> ServerConfig { data } -#[crate::export] +#[macros::export] pub fn load_config() -> Config { let server_config = read_config_file(); let version = VERSION.to_owned(); diff --git a/packages/backend-rs/src/federation/acct.rs b/packages/backend-rs/src/federation/acct.rs index b07cb71448..816e75baf2 100644 --- a/packages/backend-rs/src/federation/acct.rs +++ b/packages/backend-rs/src/federation/acct.rs @@ -1,7 +1,7 @@ use std::{fmt, str::FromStr}; #[cfg_attr(test, derive(Debug, PartialEq))] -#[crate::export(object)] +#[macros::export(object)] pub struct Acct { pub username: String, pub host: Option<String>, @@ -51,12 +51,12 @@ impl From<Acct> for String { } } -#[crate::ts_export] +#[macros::ts_export] pub fn string_to_acct(acct: &str) -> Acct { Acct::from_str(acct).unwrap() } -#[crate::ts_export] +#[macros::ts_export] pub fn acct_to_string(acct: &Acct) -> String { acct.to_string() } diff --git a/packages/backend-rs/src/federation/nodeinfo/fetch.rs b/packages/backend-rs/src/federation/nodeinfo/fetch.rs index 1004bc6f56..4f11821054 100644 --- a/packages/backend-rs/src/federation/nodeinfo/fetch.rs +++ b/packages/backend-rs/src/federation/nodeinfo/fetch.rs @@ -91,7 +91,7 @@ async fn fetch_nodeinfo_impl(nodeinfo_link: &str) -> Result<Nodeinfo20, Error> { type Nodeinfo = Nodeinfo20; /// Fetches and returns the NodeInfo (version 2.0) of a remote server. -#[crate::export] +#[macros::export] pub async fn fetch_nodeinfo(host: &str) -> Result<Nodeinfo, Error> { tracing::info!("fetching from {}", host); let links = fetch_nodeinfo_links(host).await?; diff --git a/packages/backend-rs/src/federation/nodeinfo/generate.rs b/packages/backend-rs/src/federation/nodeinfo/generate.rs index b37652637c..4d0a007823 100644 --- a/packages/backend-rs/src/federation/nodeinfo/generate.rs +++ b/packages/backend-rs/src/federation/nodeinfo/generate.rs @@ -161,17 +161,17 @@ pub enum Error { Json(#[from] serde_json::Error), } -#[crate::ts_export(js_name = "nodeinfo_2_1")] +#[macros::ts_export(js_name = "nodeinfo_2_1")] pub async fn nodeinfo_2_1_as_json() -> Result<serde_json::Value, Error> { Ok(serde_json::to_value(nodeinfo_2_1().await?)?) } -#[crate::ts_export(js_name = "nodeinfo_2_0")] +#[macros::ts_export(js_name = "nodeinfo_2_0")] pub async fn nodeinfo_2_0_as_json() -> Result<serde_json::Value, Error> { Ok(serde_json::to_value(nodeinfo_2_0().await?)?) } -#[crate::ts_export(js_name = "updateNodeinfoCache")] +#[macros::ts_export(js_name = "updateNodeinfoCache")] pub async fn update_cache() -> Result<(), DbErr> { nodeinfo_2_1_impl(false).await?; Ok(()) diff --git a/packages/backend-rs/src/federation/nodeinfo/schema.rs b/packages/backend-rs/src/federation/nodeinfo/schema.rs index 82f1dfe728..4abb02562e 100644 --- a/packages/backend-rs/src/federation/nodeinfo/schema.rs +++ b/packages/backend-rs/src/federation/nodeinfo/schema.rs @@ -34,7 +34,7 @@ pub struct Nodeinfo21 { #[cfg_attr(test, derive(Debug, PartialEq))] #[derive(Deserialize, Serialize)] #[serde(rename_all = "camelCase")] -#[crate::export(object, js_name = "Nodeinfo")] +#[macros::export(object, js_name = "Nodeinfo")] pub struct Nodeinfo20 { /// The schema version, must be 2.0. pub version: String, @@ -71,7 +71,7 @@ pub struct Software21 { #[cfg_attr(test, derive(Debug, PartialEq))] #[derive(Deserialize, Serialize)] #[serde(rename_all = "camelCase")] -#[crate::export(object)] +#[macros::export(object)] pub struct Software20 { /// The canonical name of this server software. pub name: String, @@ -82,7 +82,7 @@ pub struct Software20 { #[cfg_attr(test, derive(Debug, PartialEq))] #[derive(Deserialize, Serialize)] #[serde(rename_all = "lowercase")] -#[crate::derive_clone_and_export] +#[macros::derive_clone_and_export] pub enum Protocol { Activitypub, Buddycloud, @@ -100,7 +100,7 @@ pub enum Protocol { #[cfg_attr(test, derive(Debug, PartialEq))] #[derive(Clone, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] -#[crate::export(object)] +#[macros::export(object)] pub struct Services { /// The third party sites this server can retrieve messages from for combined display with regular traffic. pub inbound: Vec<Inbound>, @@ -112,7 +112,7 @@ pub struct Services { #[cfg_attr(test, derive(Debug, PartialEq))] #[derive(Deserialize, Serialize)] #[serde(rename_all = "lowercase")] -#[crate::derive_clone_and_export] +#[macros::derive_clone_and_export] pub enum Inbound { #[serde(rename = "atom1.0")] Atom1, @@ -131,7 +131,7 @@ pub enum Inbound { #[cfg_attr(test, derive(Debug, PartialEq))] #[derive(Deserialize, Serialize)] #[serde(rename_all = "lowercase")] -#[crate::derive_clone_and_export] +#[macros::derive_clone_and_export] pub enum Outbound { #[serde(rename = "atom1.0")] Atom1, @@ -169,7 +169,7 @@ pub enum Outbound { #[cfg_attr(test, derive(Debug, PartialEq))] #[derive(Clone, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] -#[crate::export(object)] +#[macros::export(object)] pub struct Usage { pub users: Users, pub local_posts: Option<u32>, @@ -180,7 +180,7 @@ pub struct Usage { #[cfg_attr(test, derive(Debug, PartialEq))] #[derive(Clone, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] -#[crate::export(object)] +#[macros::export(object)] pub struct Users { pub total: Option<u32>, pub active_halfyear: Option<u32>, diff --git a/packages/backend-rs/src/init/greet.rs b/packages/backend-rs/src/init/greet.rs index 323548e59c..01f795ed00 100644 --- a/packages/backend-rs/src/init/greet.rs +++ b/packages/backend-rs/src/init/greet.rs @@ -12,7 +12,7 @@ const GREETING_MESSAGE: &str = "\ "; /// Prints the greeting message and the Firefish version to stdout. -#[crate::export] +#[macros::export] pub fn greet() { println!("{}", GREETING_MESSAGE); diff --git a/packages/backend-rs/src/init/log.rs b/packages/backend-rs/src/init/log.rs index beb49decdc..47466735e3 100644 --- a/packages/backend-rs/src/init/log.rs +++ b/packages/backend-rs/src/init/log.rs @@ -3,7 +3,7 @@ use tracing::Level; use tracing_subscriber::FmtSubscriber; /// Initializes the [tracing] logger. -#[crate::export(js_name = "initializeRustLogger")] +#[macros::export(js_name = "initializeRustLogger")] pub fn initialize_logger() { let mut builder = FmtSubscriber::builder(); diff --git a/packages/backend-rs/src/init/system_info.rs b/packages/backend-rs/src/init/system_info.rs index c4847cdd0d..7fde335e85 100644 --- a/packages/backend-rs/src/init/system_info.rs +++ b/packages/backend-rs/src/init/system_info.rs @@ -20,7 +20,7 @@ pub fn system_info() -> &'static std::sync::Mutex<System> { } /// Prints the server hardware information as the server info log. -#[crate::export] +#[macros::export] pub fn show_server_info() -> Result<(), SysinfoPoisonError> { let system_info = system_info().lock()?; diff --git a/packages/backend-rs/src/lib.rs b/packages/backend-rs/src/lib.rs index dbb3f734a1..1b9933fb8a 100644 --- a/packages/backend-rs/src/lib.rs +++ b/packages/backend-rs/src/lib.rs @@ -1,5 +1,3 @@ -use macros::{derive_clone_and_export, export, ts_export}; - pub mod config; pub mod database; pub mod federation; diff --git a/packages/backend-rs/src/misc/check_server_block.rs b/packages/backend-rs/src/misc/check_server_block.rs index 885507a9ae..a6355f5e94 100644 --- a/packages/backend-rs/src/misc/check_server_block.rs +++ b/packages/backend-rs/src/misc/check_server_block.rs @@ -18,7 +18,7 @@ /// # Ok(()) /// # } /// ``` -#[crate::ts_export] +#[macros::ts_export] pub async fn is_blocked_server(host: &str) -> Result<bool, sea_orm::DbErr> { Ok(crate::config::local_server_info() .await? @@ -45,7 +45,7 @@ pub async fn is_blocked_server(host: &str) -> Result<bool, sea_orm::DbErr> { /// # Ok(()) /// # } /// ``` -#[crate::ts_export] +#[macros::ts_export] pub async fn is_silenced_server(host: &str) -> Result<bool, sea_orm::DbErr> { Ok(crate::config::local_server_info() .await? @@ -73,7 +73,7 @@ pub async fn is_silenced_server(host: &str) -> Result<bool, sea_orm::DbErr> { /// # Ok(()) /// # } /// ``` -#[crate::ts_export] +#[macros::ts_export] pub async fn is_allowed_server(host: &str) -> Result<bool, sea_orm::DbErr> { let meta = crate::config::local_server_info().await?; diff --git a/packages/backend-rs/src/misc/check_word_mute.rs b/packages/backend-rs/src/misc/check_word_mute.rs index 0faf946c8d..fdf4e1a8a0 100644 --- a/packages/backend-rs/src/misc/check_word_mute.rs +++ b/packages/backend-rs/src/misc/check_word_mute.rs @@ -3,7 +3,7 @@ use once_cell::sync::Lazy; use regex::Regex; use sea_orm::DbErr; -#[crate::export(object)] +#[macros::export(object)] pub struct PartialNoteToCheckWordMute { pub file_ids: Vec<String>, pub text: Option<String>, @@ -49,7 +49,7 @@ fn check_word_mute_impl( /// * `note` : [PartialNoteToCheckWordMute] object /// * `muted_words` : list of muted keyword lists (each array item is a space-separated keyword list that represents an AND condition) /// * `muted_patterns` : list of JavaScript-style (e.g., `/foo/i`) regular expressions -#[crate::export] +#[macros::export] pub async fn check_word_mute( note: PartialNoteToCheckWordMute, muted_words: &[String], diff --git a/packages/backend-rs/src/misc/convert_host.rs b/packages/backend-rs/src/misc/convert_host.rs index 2850d4cb29..0de4d1912d 100644 --- a/packages/backend-rs/src/misc/convert_host.rs +++ b/packages/backend-rs/src/misc/convert_host.rs @@ -13,7 +13,7 @@ pub enum Error { NoHostname, } -#[crate::ts_export] +#[macros::ts_export] pub fn get_full_ap_account(username: &str, host: Option<&str>) -> Result<String, Error> { Ok(match host { Some(host) => format!("{}@{}", username, to_puny(host)?), @@ -21,7 +21,7 @@ pub fn get_full_ap_account(username: &str, host: Option<&str>) -> Result<String, }) } -#[crate::ts_export] +#[macros::ts_export] pub fn is_self_host(host: Option<&str>) -> Result<bool, Error> { Ok(match host { Some(host) => extract_host(&crate::config::CONFIG.url)? == to_puny(host)?, @@ -29,12 +29,12 @@ pub fn is_self_host(host: Option<&str>) -> Result<bool, Error> { }) } -#[crate::ts_export] +#[macros::ts_export] pub fn is_same_origin(uri: &str) -> Result<bool, Error> { Ok(url::Url::parse(uri)?.origin().ascii_serialization() == crate::config::CONFIG.url) } -#[crate::ts_export] +#[macros::ts_export] pub fn extract_host(uri: &str) -> Result<String, Error> { url::Url::parse(uri)? .host_str() @@ -42,7 +42,7 @@ pub fn extract_host(uri: &str) -> Result<String, Error> { .and_then(|v| Ok(to_puny(v)?)) } -#[crate::ts_export] +#[macros::ts_export] pub fn to_puny(host: &str) -> Result<String, idna::Errors> { idna::domain_to_ascii(host) } diff --git a/packages/backend-rs/src/misc/emoji.rs b/packages/backend-rs/src/misc/emoji.rs index a19fc6229d..47c2e0debe 100644 --- a/packages/backend-rs/src/misc/emoji.rs +++ b/packages/backend-rs/src/misc/emoji.rs @@ -1,6 +1,6 @@ //! This module is used in the TypeScript backend only. -#[crate::ts_export] +#[macros::ts_export] pub fn is_unicode_emoji(s: &str) -> bool { emojis::get(s).is_some() } diff --git a/packages/backend-rs/src/misc/escape_sql.rs b/packages/backend-rs/src/misc/escape_sql.rs index 5ff7e51729..747ceb51c7 100644 --- a/packages/backend-rs/src/misc/escape_sql.rs +++ b/packages/backend-rs/src/misc/escape_sql.rs @@ -1,11 +1,11 @@ /// Escapes `%` and `\` in the given string. -#[crate::export] +#[macros::export] pub fn sql_like_escape(src: &str) -> String { src.replace('%', r"\%").replace('_', r"\_") } /// Returns `true` if `src` does not contain suspicious characters like `%`. -#[crate::export] +#[macros::export] pub fn safe_for_sql(src: &str) -> bool { !src.contains([ '\0', '\x08', '\x09', '\x1a', '\n', '\r', '"', '\'', '\\', '%', diff --git a/packages/backend-rs/src/misc/format_milliseconds.rs b/packages/backend-rs/src/misc/format_milliseconds.rs index b30af15847..148e5791b5 100644 --- a/packages/backend-rs/src/misc/format_milliseconds.rs +++ b/packages/backend-rs/src/misc/format_milliseconds.rs @@ -1,5 +1,5 @@ /// Converts milliseconds to a human readable string. -#[crate::export] +#[macros::export] pub fn format_milliseconds(milliseconds: u32) -> String { let mut seconds = milliseconds / 1000; let mut minutes = seconds / 60; diff --git a/packages/backend-rs/src/misc/get_image_size.rs b/packages/backend-rs/src/misc/get_image_size.rs index 58f9783fe0..1964c9cbd9 100644 --- a/packages/backend-rs/src/misc/get_image_size.rs +++ b/packages/backend-rs/src/misc/get_image_size.rs @@ -44,13 +44,13 @@ const BROWSER_SAFE_IMAGE_TYPES: [ImageFormat; 8] = [ static MTX_GUARD: Mutex<()> = Mutex::const_new(()); #[cfg_attr(test, derive(Debug, PartialEq))] -#[crate::export(object)] +#[macros::export(object)] pub struct ImageSize { pub width: u32, pub height: u32, } -#[crate::export] +#[macros::export] pub async fn get_image_size_from_url(url: &str) -> Result<ImageSize, Error> { let attempted: bool; diff --git a/packages/backend-rs/src/misc/is_quote.rs b/packages/backend-rs/src/misc/is_quote.rs index 42e792f956..3ee15a5873 100644 --- a/packages/backend-rs/src/misc/is_quote.rs +++ b/packages/backend-rs/src/misc/is_quote.rs @@ -4,7 +4,7 @@ use crate::model::entity::note; // https://github.com/napi-rs/napi-rs/issues/2060 type Note = note::Model; -#[crate::export] +#[macros::export] pub fn is_quote(note: Note) -> bool { note.renote_id.is_some() && (note.text.is_some() || note.has_poll || !note.file_ids.is_empty()) } diff --git a/packages/backend-rs/src/misc/is_safe_url.rs b/packages/backend-rs/src/misc/is_safe_url.rs index 1e5c5244ce..603710310f 100644 --- a/packages/backend-rs/src/misc/is_safe_url.rs +++ b/packages/backend-rs/src/misc/is_safe_url.rs @@ -1,4 +1,4 @@ -#[crate::export] +#[macros::export] pub fn is_safe_url(url: &str) -> bool { if let Ok(url) = url.parse::<url::Url>() { if url.host_str().unwrap_or_default() == "unix" diff --git a/packages/backend-rs/src/misc/latest_version.rs b/packages/backend-rs/src/misc/latest_version.rs index 58f50d0b0b..1f330f4d2e 100644 --- a/packages/backend-rs/src/misc/latest_version.rs +++ b/packages/backend-rs/src/misc/latest_version.rs @@ -46,7 +46,7 @@ async fn get_latest_version() -> Result<String, Error> { } /// Returns the latest Firefish version. -#[crate::export] +#[macros::export] pub async fn latest_version() -> Result<String, Error> { let version: Option<String> = cache::get_one(cache::Category::FetchUrl, UPSTREAM_PACKAGE_JSON_URL).await?; diff --git a/packages/backend-rs/src/misc/mastodon_id.rs b/packages/backend-rs/src/misc/mastodon_id.rs index bb837c42f7..65fbd4d057 100644 --- a/packages/backend-rs/src/misc/mastodon_id.rs +++ b/packages/backend-rs/src/misc/mastodon_id.rs @@ -1,10 +1,10 @@ -#[crate::export] +#[macros::export] pub fn to_mastodon_id(firefish_id: &str) -> Option<String> { let decoded: [u8; 16] = basen::BASE36.decode_var_len(firefish_id)?; Some(basen::BASE10.encode_var_len(&decoded)) } -#[crate::export] +#[macros::export] pub fn from_mastodon_id(mastodon_id: &str) -> Option<String> { let decoded: [u8; 16] = basen::BASE10.decode_var_len(mastodon_id)?; Some(basen::BASE36.encode_var_len(&decoded)) diff --git a/packages/backend-rs/src/misc/note/summarize.rs b/packages/backend-rs/src/misc/note/summarize.rs index 83bbb0246d..9649fc9345 100644 --- a/packages/backend-rs/src/misc/note/summarize.rs +++ b/packages/backend-rs/src/misc/note/summarize.rs @@ -1,4 +1,4 @@ -#[crate::export(js_name = "getNoteSummary")] +#[macros::export(js_name = "getNoteSummary")] pub fn summarize_impl( file_ids: &[String], text: Option<String>, diff --git a/packages/backend-rs/src/misc/nyaify.rs b/packages/backend-rs/src/misc/nyaify.rs index 5e343f5838..c58795f798 100644 --- a/packages/backend-rs/src/misc/nyaify.rs +++ b/packages/backend-rs/src/misc/nyaify.rs @@ -20,7 +20,7 @@ use regex::{Captures, Regex}; /// # use backend_rs::misc::nyaify::nyaify; /// assert_eq!(nyaify("I'll take a nap.", Some("en")), "I'll take a nyap."); /// ``` -#[crate::export] +#[macros::export] pub fn nyaify(text: &str, lang: Option<&str>) -> String { let mut to_return = text.to_owned(); diff --git a/packages/backend-rs/src/misc/password.rs b/packages/backend-rs/src/misc/password.rs index 507313c778..bc2025f275 100644 --- a/packages/backend-rs/src/misc/password.rs +++ b/packages/backend-rs/src/misc/password.rs @@ -7,7 +7,7 @@ use argon2::{ }; /// Hashes the given password using [argon2] algorithm. -#[crate::export] +#[macros::export] pub fn hash_password(password: &str) -> Result<String, password_hash::errors::Error> { let salt = SaltString::generate(&mut OsRng); Ok(Argon2::default() @@ -26,7 +26,7 @@ pub enum Error { } /// Checks whether the given password and hash match. -#[crate::export] +#[macros::export] pub fn verify_password(password: &str, hash: &str) -> Result<bool, Error> { if is_old_password_algorithm(hash) { Ok(bcrypt::verify(password, hash)?) @@ -40,7 +40,7 @@ pub fn verify_password(password: &str, hash: &str) -> Result<bool, Error> { /// Returns whether the [bcrypt] algorithm is used for the password hash. #[inline] -#[crate::export] +#[macros::export] pub fn is_old_password_algorithm(hash: &str) -> bool { // bcrypt hashes start with $2[ab]$ hash.starts_with("$2") diff --git a/packages/backend-rs/src/misc/reaction.rs b/packages/backend-rs/src/misc/reaction.rs index 662e6ac766..01441b90a3 100644 --- a/packages/backend-rs/src/misc/reaction.rs +++ b/packages/backend-rs/src/misc/reaction.rs @@ -5,14 +5,14 @@ use sea_orm::prelude::*; use std::collections::HashMap; #[cfg_attr(test, derive(PartialEq, Debug))] -#[crate::export(object)] +#[macros::export(object)] pub struct DecodedReaction { pub reaction: String, pub name: Option<String>, pub host: Option<String>, } -#[crate::export] +#[macros::export] pub fn decode_reaction(reaction: &str) -> DecodedReaction { // Misskey allows you to include "+" and "-" in emoji shortcodes // MFM spec: https://github.com/misskey-dev/mfm.js/blob/6aaf68089023c6adebe44123eebbc4dcd75955e0/docs/syntax.md?plain=1#L583 @@ -38,7 +38,7 @@ pub fn decode_reaction(reaction: &str) -> DecodedReaction { } } -#[crate::export] +#[macros::export] pub fn count_reactions(reactions: &HashMap<String, u32>) -> HashMap<String, u32> { let mut res = HashMap::<String, u32>::new(); @@ -62,7 +62,7 @@ pub enum Error { Db(#[from] DbErr), } -#[crate::export] +#[macros::export] pub async fn to_db_reaction(reaction: Option<&str>, host: Option<&str>) -> Result<String, Error> { if let Some(reaction) = reaction { // FIXME: Is it okay to do this only here? diff --git a/packages/backend-rs/src/misc/remove_old_attestation_challenges.rs b/packages/backend-rs/src/misc/remove_old_attestation_challenges.rs index a36c34c664..725f6ac481 100644 --- a/packages/backend-rs/src/misc/remove_old_attestation_challenges.rs +++ b/packages/backend-rs/src/misc/remove_old_attestation_challenges.rs @@ -5,7 +5,7 @@ use chrono::{Duration, Utc}; use sea_orm::prelude::*; /// Delete all entries in the [attestation_challenge] table created at more than 5 minutes ago -#[crate::export] +#[macros::export] pub async fn remove_old_attestation_challenges() -> Result<(), DbErr> { let res = attestation_challenge::Entity::delete_many() .filter(attestation_challenge::Column::CreatedAt.lt(Utc::now() - Duration::minutes(5))) diff --git a/packages/backend-rs/src/misc/system_info.rs b/packages/backend-rs/src/misc/system_info.rs index 2c4f6cdcf2..4b31ceaaee 100644 --- a/packages/backend-rs/src/misc/system_info.rs +++ b/packages/backend-rs/src/misc/system_info.rs @@ -5,14 +5,14 @@ use sysinfo::{Disks, MemoryRefreshKind}; // TODO: i64 -> u64 (we can't export u64 to Node.js) -#[crate::export(object)] +#[macros::export(object)] pub struct Cpu { pub model: String, // TODO: u16 -> usize (we can't export usize to Node.js) pub cores: u16, } -#[crate::export(object)] +#[macros::export(object)] pub struct Memory { /// Total memory amount in bytes pub total: i64, @@ -22,7 +22,7 @@ pub struct Memory { pub available: i64, } -#[crate::export(object)] +#[macros::export(object)] pub struct Storage { /// Total storage space in bytes pub total: i64, @@ -30,7 +30,7 @@ pub struct Storage { pub used: i64, } -#[crate::export] +#[macros::export] pub fn cpu_info() -> Result<Cpu, SysinfoPoisonError> { let system_info = system_info().lock()?; @@ -46,7 +46,7 @@ pub fn cpu_info() -> Result<Cpu, SysinfoPoisonError> { }) } -#[crate::export] +#[macros::export] pub fn cpu_usage() -> Result<f32, SysinfoPoisonError> { let mut system_info = system_info().lock()?; system_info.refresh_cpu_usage(); @@ -57,7 +57,7 @@ pub fn cpu_usage() -> Result<f32, SysinfoPoisonError> { Ok(total_cpu_usage / (cpu_threads as f32)) } -#[crate::export] +#[macros::export] pub fn memory_usage() -> Result<Memory, SysinfoPoisonError> { let mut system_info = system_info().lock()?; @@ -70,7 +70,7 @@ pub fn memory_usage() -> Result<Memory, SysinfoPoisonError> { }) } -#[crate::export] +#[macros::export] pub fn storage_usage() -> Option<Storage> { // Get the first disk that is actualy used (has available space & has at least 1 GB total space). let disks = Disks::new_with_refreshed_list(); diff --git a/packages/backend-rs/src/service/antenna/process_new_note.rs b/packages/backend-rs/src/service/antenna/process_new_note.rs index 7e86fbd31f..13fc7fdcbb 100644 --- a/packages/backend-rs/src/service/antenna/process_new_note.rs +++ b/packages/backend-rs/src/service/antenna/process_new_note.rs @@ -37,7 +37,7 @@ pub enum Error { // https://github.com/napi-rs/napi-rs/issues/2060 type Note = note::Model; -#[crate::export] +#[macros::export] pub async fn update_antennas_on_new_note( note: &Note, note_author: &Acct, diff --git a/packages/backend-rs/src/service/antenna/update.rs b/packages/backend-rs/src/service/antenna/update.rs index 350b9ba9db..169e574379 100644 --- a/packages/backend-rs/src/service/antenna/update.rs +++ b/packages/backend-rs/src/service/antenna/update.rs @@ -1,6 +1,6 @@ //! This module is (currently) used in the TypeScript backend only. -#[crate::ts_export] +#[macros::ts_export] pub async fn update_antenna_cache() -> Result<(), sea_orm::DbErr> { super::cache::update().await?; Ok(()) diff --git a/packages/backend-rs/src/service/note/watch.rs b/packages/backend-rs/src/service/note/watch.rs index d63ce00e85..144f4e2360 100644 --- a/packages/backend-rs/src/service/note/watch.rs +++ b/packages/backend-rs/src/service/note/watch.rs @@ -1,7 +1,7 @@ use crate::{database::db_conn, model::entity::note_watching, util::id::gen_id_at}; use sea_orm::{prelude::*, ActiveValue}; -#[crate::export] +#[macros::export] pub async fn watch_note( watcher_id: &str, note_author_id: &str, @@ -24,7 +24,7 @@ pub async fn watch_note( Ok(()) } -#[crate::export] +#[macros::export] pub async fn unwatch_note(watcher_id: &str, note_id: &str) -> Result<(), DbErr> { let db = db_conn().await?; diff --git a/packages/backend-rs/src/service/push_notification.rs b/packages/backend-rs/src/service/push_notification.rs index 8bde9987d3..29de12fca5 100644 --- a/packages/backend-rs/src/service/push_notification.rs +++ b/packages/backend-rs/src/service/push_notification.rs @@ -31,7 +31,7 @@ fn get_client() -> Result<IsahcWebPushClient, Error> { .cloned()?) } -#[crate::export] +#[macros::export] pub enum PushNotificationKind { Generic, Chat, @@ -129,7 +129,7 @@ async fn handle_web_push_failure( Ok(()) } -#[crate::export] +#[macros::export] pub async fn send_push_notification( receiver_user_id: &str, kind: PushNotificationKind, diff --git a/packages/backend-rs/src/service/stream.rs b/packages/backend-rs/src/service/stream.rs index 36d7f841fe..412ed3a3a7 100644 --- a/packages/backend-rs/src/service/stream.rs +++ b/packages/backend-rs/src/service/stream.rs @@ -54,7 +54,7 @@ pub enum Stream { }, } -#[crate::export] +#[macros::export] pub enum ChatEvent { Message, Read, diff --git a/packages/backend-rs/src/service/stream/channel.rs b/packages/backend-rs/src/service/stream/channel.rs index 028aab69c7..b1bb865fa1 100644 --- a/packages/backend-rs/src/service/stream/channel.rs +++ b/packages/backend-rs/src/service/stream/channel.rs @@ -1,6 +1,6 @@ use crate::service::stream::{publish_to_stream, Error, Stream}; -#[crate::export(js_name = "publishToChannelStream")] +#[macros::export(js_name = "publishToChannelStream")] pub async fn publish(channel_id: String, user_id: String) -> Result<(), Error> { publish_to_stream( &Stream::Channel { channel_id }, diff --git a/packages/backend-rs/src/service/stream/chat.rs b/packages/backend-rs/src/service/stream/chat.rs index 2f60ff4015..88532c7e86 100644 --- a/packages/backend-rs/src/service/stream/chat.rs +++ b/packages/backend-rs/src/service/stream/chat.rs @@ -3,7 +3,7 @@ use crate::service::stream::{publish_to_stream, ChatEvent, Error, Stream}; // We want to merge `kind` and `object` into a single enum // https://github.com/napi-rs/napi-rs/issues/2036 -#[crate::export(js_name = "publishToChatStream")] +#[macros::export(js_name = "publishToChatStream")] pub async fn publish( sender_user_id: String, receiver_user_id: String, diff --git a/packages/backend-rs/src/service/stream/chat_index.rs b/packages/backend-rs/src/service/stream/chat_index.rs index e686db8149..25b2913f2c 100644 --- a/packages/backend-rs/src/service/stream/chat_index.rs +++ b/packages/backend-rs/src/service/stream/chat_index.rs @@ -1,6 +1,6 @@ use crate::service::stream::{publish_to_stream, Error, Stream}; -#[crate::export] +#[macros::export] pub enum ChatIndexEvent { Message, Read, @@ -9,7 +9,7 @@ pub enum ChatIndexEvent { // We want to merge `kind` and `object` into a single enum // https://github.com/napi-rs/napi-rs/issues/2036 -#[crate::export(js_name = "publishToChatIndexStream")] +#[macros::export(js_name = "publishToChatIndexStream")] pub async fn publish( user_id: String, kind: ChatIndexEvent, diff --git a/packages/backend-rs/src/service/stream/custom_emoji.rs b/packages/backend-rs/src/service/stream/custom_emoji.rs index 164d89b957..890d550d6a 100644 --- a/packages/backend-rs/src/service/stream/custom_emoji.rs +++ b/packages/backend-rs/src/service/stream/custom_emoji.rs @@ -4,7 +4,7 @@ use serde::Serialize; // TODO: define schema type in other place #[derive(Serialize)] #[serde(rename_all = "camelCase")] -#[crate::export(object)] +#[macros::export(object)] pub struct PackedEmoji { pub id: String, pub aliases: Vec<String>, @@ -17,7 +17,7 @@ pub struct PackedEmoji { pub height: Option<i32>, } -#[crate::export(js_name = "publishToBroadcastStream")] +#[macros::export(js_name = "publishToBroadcastStream")] pub async fn publish(emoji: &PackedEmoji) -> Result<(), Error> { publish_to_stream( &Stream::CustomEmoji, diff --git a/packages/backend-rs/src/service/stream/drive.rs b/packages/backend-rs/src/service/stream/drive.rs index c3b49d0db3..21ddf1f4b2 100644 --- a/packages/backend-rs/src/service/stream/drive.rs +++ b/packages/backend-rs/src/service/stream/drive.rs @@ -1,13 +1,13 @@ use crate::service::stream::{publish_to_stream, Error, Stream}; -#[crate::export] +#[macros::export] pub enum DriveFileEvent { Create, Update, Delete, } -#[crate::export] +#[macros::export] pub enum DriveFolderEvent { Create, Update, @@ -17,7 +17,7 @@ pub enum DriveFolderEvent { // We want to merge `kind` and `object` into a single enum and merge the 2 functions // https://github.com/napi-rs/napi-rs/issues/2036 -#[crate::export(js_name = "publishToDriveFileStream")] +#[macros::export(js_name = "publishToDriveFileStream")] pub async fn publish_file( user_id: String, kind: DriveFileEvent, @@ -37,7 +37,7 @@ pub async fn publish_file( .await } -#[crate::export(js_name = "publishToDriveFolderStream")] +#[macros::export(js_name = "publishToDriveFolderStream")] pub async fn publish_folder( user_id: String, kind: DriveFolderEvent, diff --git a/packages/backend-rs/src/service/stream/group_chat.rs b/packages/backend-rs/src/service/stream/group_chat.rs index 49ebc299d2..005a523f1c 100644 --- a/packages/backend-rs/src/service/stream/group_chat.rs +++ b/packages/backend-rs/src/service/stream/group_chat.rs @@ -3,7 +3,7 @@ use crate::service::stream::{publish_to_stream, ChatEvent, Error, Stream}; // We want to merge `kind` and `object` into a single enum // https://github.com/napi-rs/napi-rs/issues/2036 -#[crate::export(js_name = "publishToGroupChatStream")] +#[macros::export(js_name = "publishToGroupChatStream")] pub async fn publish( group_id: String, kind: ChatEvent, diff --git a/packages/backend-rs/src/service/stream/moderation.rs b/packages/backend-rs/src/service/stream/moderation.rs index 218441e15f..3ac261ff50 100644 --- a/packages/backend-rs/src/service/stream/moderation.rs +++ b/packages/backend-rs/src/service/stream/moderation.rs @@ -3,7 +3,7 @@ use serde::Serialize; #[derive(Serialize)] #[serde(rename_all = "camelCase")] -#[crate::export(object)] +#[macros::export(object)] pub struct AbuseUserReportLike { pub id: String, pub target_user_id: String, @@ -11,7 +11,7 @@ pub struct AbuseUserReportLike { pub comment: String, } -#[crate::export(js_name = "publishToModerationStream")] +#[macros::export(js_name = "publishToModerationStream")] pub async fn publish(moderator_id: String, report: &AbuseUserReportLike) -> Result<(), Error> { publish_to_stream( &Stream::Moderation { moderator_id }, diff --git a/packages/backend-rs/src/service/stream/notes.rs b/packages/backend-rs/src/service/stream/notes.rs index 6c2336e347..8832bc03e3 100644 --- a/packages/backend-rs/src/service/stream/notes.rs +++ b/packages/backend-rs/src/service/stream/notes.rs @@ -7,7 +7,7 @@ use crate::{ // https://github.com/napi-rs/napi-rs/issues/2060 type Note = note::Model; -#[crate::export(js_name = "publishToNotesStream")] +#[macros::export(js_name = "publishToNotesStream")] pub async fn publish(note: &Note) -> Result<(), Error> { publish_to_stream(&Stream::Notes, None, Some(serde_json::to_string(note)?)).await } diff --git a/packages/backend-rs/src/util/id.rs b/packages/backend-rs/src/util/id.rs index f61454d9c3..2d384db78c 100644 --- a/packages/backend-rs/src/util/id.rs +++ b/packages/backend-rs/src/util/id.rs @@ -52,7 +52,7 @@ pub struct InvalidIdError { id: String, } -#[crate::export] +#[macros::export] pub fn get_timestamp(id: &str) -> Result<i64, InvalidIdError> { let n: Option<u64> = BASE36.decode_var_len(&id[0..8]); if let Some(n) = n { @@ -68,13 +68,13 @@ pub fn get_timestamp(id: &str) -> Result<i64, InvalidIdError> { /// in the same millisecond to reach 50% chance of collision. /// /// Ref: <https://github.com/paralleldrive/cuid2#parameterized-length> -#[crate::export] +#[macros::export] pub fn gen_id() -> String { create_id(&Utc::now().naive_utc()) } /// Generate an ID using a specific datetime -#[crate::export] +#[macros::export] pub fn gen_id_at(date: DateTime<Utc>) -> String { create_id(&date.naive_utc()) } diff --git a/packages/backend-rs/src/util/random.rs b/packages/backend-rs/src/util/random.rs index 738926576d..0c35657a47 100644 --- a/packages/backend-rs/src/util/random.rs +++ b/packages/backend-rs/src/util/random.rs @@ -3,7 +3,7 @@ use rand::{distributions::Alphanumeric, thread_rng, Rng}; /// Generates a random string based on [thread_rng] and [Alphanumeric]. -#[crate::export] +#[macros::export] pub fn generate_secure_random_string(length: u16) -> String { thread_rng() .sample_iter(Alphanumeric) @@ -12,7 +12,7 @@ pub fn generate_secure_random_string(length: u16) -> String { .collect() } -#[crate::export] +#[macros::export] pub fn generate_user_token() -> String { generate_secure_random_string(16) } From e6735519dfd5bbc85f9d09e9ce78666598ddcc4c Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Wed, 12 Jun 2024 03:50:40 +0900 Subject: [PATCH 08/16] chore (macros-impl): allow clippy::items_after_test_module --- packages/macro-rs/macros-impl/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/macro-rs/macros-impl/src/lib.rs b/packages/macro-rs/macros-impl/src/lib.rs index 8310f17148..9e4a70240e 100644 --- a/packages/macro-rs/macros-impl/src/lib.rs +++ b/packages/macro-rs/macros-impl/src/lib.rs @@ -1,2 +1,4 @@ +#![allow(clippy::items_after_test_module)] + pub mod napi; mod util; From 84c4701a493b4700b00ab05df46728d56d0ee6f1 Mon Sep 17 00:00:00 2001 From: CI <project_7_bot_1bfaee5701aed20091a86249a967a6c1@noreply.firefish.dev> Date: Tue, 11 Jun 2024 20:05:04 +0000 Subject: [PATCH 09/16] chore(deps): update dependency webpack to v5.92.0 --- packages/backend/package.json | 2 +- pnpm-lock.yaml | 36 +++++++++++++++++------------------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index abb315b15c..756fb76a5a 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -177,7 +177,7 @@ "tsconfig-paths": "4.2.0", "type-fest": "4.20.0", "typescript": "5.4.5", - "webpack": "5.91.0", + "webpack": "5.92.0", "ws": "8.17.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 44cea2104b..4c893b0f37 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -490,10 +490,10 @@ importers: version: 2.0.0 swc-loader: specifier: 0.2.6 - version: 0.2.6(@swc/core@1.5.28)(webpack@5.91.0(@swc/core@1.5.28)) + version: 0.2.6(@swc/core@1.5.28)(webpack@5.92.0(@swc/core@1.5.28)) ts-loader: specifier: 9.5.1 - version: 9.5.1(typescript@5.4.5)(webpack@5.91.0(@swc/core@1.5.28)) + version: 9.5.1(typescript@5.4.5)(webpack@5.92.0(@swc/core@1.5.28)) ts-node: specifier: 10.9.2 version: 10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5) @@ -507,8 +507,8 @@ importers: specifier: 5.4.5 version: 5.4.5 webpack: - specifier: 5.91.0 - version: 5.91.0(@swc/core@1.5.28) + specifier: 5.92.0 + version: 5.92.0(@swc/core@1.5.28) ws: specifier: 8.17.0 version: 8.17.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -2847,8 +2847,8 @@ packages: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} - acorn-import-assertions@1.9.0: - resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} + acorn-import-attributes@1.9.5: + resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} peerDependencies: acorn: ^8 @@ -7841,8 +7841,8 @@ packages: resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} engines: {node: '>=10.13.0'} - webpack@5.91.0: - resolution: {integrity: sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==} + webpack@5.92.0: + resolution: {integrity: sha512-Bsw2X39MYIgxouNATyVpCNVWBCuUwDgWtN78g6lSdPJRLaQ/PUVm/oXcaRAyY/sMFoKFQrsPeqvTizWtq7QPCA==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -10319,7 +10319,7 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 - acorn-import-assertions@1.9.0(acorn@8.11.3): + acorn-import-attributes@1.9.5(acorn@8.11.3): dependencies: acorn: 8.11.3 @@ -15468,11 +15468,11 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - swc-loader@0.2.6(@swc/core@1.5.28)(webpack@5.91.0(@swc/core@1.5.28)): + swc-loader@0.2.6(@swc/core@1.5.28)(webpack@5.92.0(@swc/core@1.5.28)): dependencies: '@swc/core': 1.5.28 '@swc/counter': 0.1.3 - webpack: 5.91.0(@swc/core@1.5.28) + webpack: 5.92.0(@swc/core@1.5.28) swiper@11.1.4: {} @@ -15513,14 +15513,14 @@ snapshots: fast-fifo: 1.3.2 streamx: 2.18.0 - terser-webpack-plugin@5.3.10(@swc/core@1.5.28)(webpack@5.91.0(@swc/core@1.5.28)): + terser-webpack-plugin@5.3.10(@swc/core@1.5.28)(webpack@5.92.0(@swc/core@1.5.28)): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.31.1 - webpack: 5.91.0(@swc/core@1.5.28) + webpack: 5.92.0(@swc/core@1.5.28) optionalDependencies: '@swc/core': 1.5.28 @@ -15665,7 +15665,7 @@ snapshots: '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.24.7) - ts-loader@9.5.1(typescript@5.4.5)(webpack@5.91.0(@swc/core@1.5.28)): + ts-loader@9.5.1(typescript@5.4.5)(webpack@5.92.0(@swc/core@1.5.28)): dependencies: chalk: 4.1.2 enhanced-resolve: 5.17.0 @@ -15673,7 +15673,7 @@ snapshots: semver: 7.6.2 source-map: 0.7.4 typescript: 5.4.5 - webpack: 5.91.0(@swc/core@1.5.28) + webpack: 5.92.0(@swc/core@1.5.28) ts-node@10.9.2(@swc/core@1.5.28)(@swc/wasm@1.2.130)(@types/node@20.14.2)(typescript@5.4.5): dependencies: @@ -16048,7 +16048,7 @@ snapshots: webpack-sources@3.2.3: {} - webpack@5.91.0(@swc/core@1.5.28): + webpack@5.92.0(@swc/core@1.5.28): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.5 @@ -16056,7 +16056,7 @@ snapshots: '@webassemblyjs/wasm-edit': 1.12.1 '@webassemblyjs/wasm-parser': 1.12.1 acorn: 8.11.3 - acorn-import-assertions: 1.9.0(acorn@8.11.3) + acorn-import-attributes: 1.9.5(acorn@8.11.3) browserslist: 4.23.1 chrome-trace-event: 1.0.4 enhanced-resolve: 5.17.0 @@ -16071,7 +16071,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(@swc/core@1.5.28)(webpack@5.91.0(@swc/core@1.5.28)) + terser-webpack-plugin: 5.3.10(@swc/core@1.5.28)(webpack@5.92.0(@swc/core@1.5.28)) watchpack: 2.4.1 webpack-sources: 3.2.3 transitivePeerDependencies: From eb5372489f4a91a6f929d4d7d1d92953793b8128 Mon Sep 17 00:00:00 2001 From: CI <project_7_bot_1bfaee5701aed20091a86249a967a6c1@noreply.firefish.dev> Date: Tue, 11 Jun 2024 20:05:26 +0000 Subject: [PATCH 10/16] fix(deps): update dependency @redocly/openapi-core to v1.15.0 --- packages/backend/package.json | 2 +- pnpm-lock.yaml | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index abb315b15c..429b564b6d 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -31,7 +31,7 @@ "@koa/router": "12.0.1", "@ladjs/koa-views": "9.0.0", "@peertube/http-signature": "1.7.0", - "@redocly/openapi-core": "1.14.0", + "@redocly/openapi-core": "1.15.0", "@sinonjs/fake-timers": "11.2.2", "adm-zip": "0.5.14", "ajv": "8.16.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 44cea2104b..b18a3a3ac9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -70,8 +70,8 @@ importers: specifier: 1.7.0 version: 1.7.0 '@redocly/openapi-core': - specifier: 1.14.0 - version: 1.14.0 + specifier: 1.15.0 + version: 1.15.0 '@sinonjs/fake-timers': specifier: 11.2.2 version: 11.2.2 @@ -2014,11 +2014,11 @@ packages: '@redocly/ajv@8.11.0': resolution: {integrity: sha512-9GWx27t7xWhDIR02PA18nzBdLcKQRgc46xNQvjFkrYk4UOmvKhJ/dawwiX0cCOeetN5LcaaiqQbVOWYK62SGHw==} - '@redocly/config@0.5.0': - resolution: {integrity: sha512-oA1ezWPT2tSV9CLk0FtZlViaFKtp+id3iAVeKBme1DdP4xUCdxEdP8umB21iLKdc6leRd5uGa+T5Ox4nHBAXWg==} + '@redocly/config@0.6.0': + resolution: {integrity: sha512-hNVN3eTxFj2nHYX0gGzZxxXwdE0DXWeWou1TIK3HYf0S9VKVxTxjO9EZbMB7iVUqaHkeqy4PSjlBQcEgD0Ftjg==} - '@redocly/openapi-core@1.14.0': - resolution: {integrity: sha512-sraF4PGVcc6t6CaYw5raO/GWeOaa6UjcEvH/+Qm7zp+q/fbWAMwbj+1QzaNvpMspCwF+xW6TddDcnXrCDmqYVA==} + '@redocly/openapi-core@1.15.0': + resolution: {integrity: sha512-ac+3nn9y/dE+cgIVgIdq7eIisjZlBEJptLsCbOVLIsR2jb+O1SznXeyqy2MkTHMSs6zM/KHP4bMQy0DGmi7K0Q==} engines: {node: '>=14.19.0', npm: '>=7.0.0'} '@rollup/plugin-alias@5.1.0': @@ -9316,12 +9316,12 @@ snapshots: require-from-string: 2.0.2 uri-js: 4.4.1 - '@redocly/config@0.5.0': {} + '@redocly/config@0.6.0': {} - '@redocly/openapi-core@1.14.0': + '@redocly/openapi-core@1.15.0': dependencies: '@redocly/ajv': 8.11.0 - '@redocly/config': 0.5.0 + '@redocly/config': 0.6.0 colorette: 1.4.0 js-levenshtein: 1.1.6 js-yaml: 4.1.0 From 175fbca72098cd8c06db1132ee20b1bc3d8cada1 Mon Sep 17 00:00:00 2001 From: CI <project_7_bot_1bfaee5701aed20091a86249a967a6c1@noreply.firefish.dev> Date: Tue, 11 Jun 2024 20:05:44 +0000 Subject: [PATCH 11/16] fix(deps): update dependency aws-sdk to v2.1639.0 --- packages/backend/package.json | 2 +- pnpm-lock.yaml | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index abb315b15c..add36b500f 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -36,7 +36,7 @@ "adm-zip": "0.5.14", "ajv": "8.16.0", "archiver": "7.0.1", - "aws-sdk": "2.1638.0", + "aws-sdk": "2.1639.0", "axios": "1.7.2", "backend-rs": "workspace:*", "blurhash": "2.0.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 44cea2104b..a629dfd232 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -85,8 +85,8 @@ importers: specifier: 7.0.1 version: 7.0.1 aws-sdk: - specifier: 2.1638.0 - version: 2.1638.0 + specifier: 2.1639.0 + version: 2.1639.0 axios: specifier: 1.7.2 version: 1.7.2 @@ -3040,8 +3040,8 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - aws-sdk@2.1638.0: - resolution: {integrity: sha512-/Li+eOMvJOLuYXimt3YPd6ec9Xvzh6L5KLfU5bjuJrltQqBcW7paL+PnFqSjm7zef+fPJT7h+8sqEcuRaGUmRA==} + aws-sdk@2.1639.0: + resolution: {integrity: sha512-3vi9ONXhROfXTjsulFurKtJ/vBjiXirhwrRY6C7QRJyI/+m9lphtBivSYynnu7q2saAqC9ArlkEWQLRFUPy+Zg==} engines: {node: '>= 10.0.0'} axios@0.24.0: @@ -10512,7 +10512,7 @@ snapshots: dependencies: possible-typed-array-names: 1.0.0 - aws-sdk@2.1638.0: + aws-sdk@2.1639.0: dependencies: buffer: 4.9.2 events: 1.1.1 @@ -10712,7 +10712,7 @@ snapshots: buffer@4.9.2: dependencies: base64-js: 1.5.1 - ieee754: 1.1.13 + ieee754: 1.2.1 isarray: 1.0.0 buffer@5.7.1: @@ -16195,7 +16195,7 @@ snapshots: xml2js@0.6.2: dependencies: - sax: 1.2.1 + sax: 1.4.1 xmlbuilder: 11.0.1 xmlbuilder@11.0.1: {} From 16720d6c146fb65a61dc486afcd6274a8c39a6de Mon Sep 17 00:00:00 2001 From: CI <project_7_bot_1bfaee5701aed20091a86249a967a6c1@noreply.firefish.dev> Date: Wed, 12 Jun 2024 04:06:23 +0000 Subject: [PATCH 12/16] chore(deps): update dependency sass to v1.77.5 --- packages/client/package.json | 2 +- pnpm-lock.yaml | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/client/package.json b/packages/client/package.json index 3b5d47929a..5d9696ee5d 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -72,7 +72,7 @@ "qrcode-vue3": "1.6.8", "rollup": "4.17.2", "s-age": "1.1.2", - "sass": "1.77.4", + "sass": "1.77.5", "seedrandom": "3.0.5", "stringz": "2.1.0", "swiper": "11.1.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 44a24cdd6f..9a367b3ff9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -586,7 +586,7 @@ importers: version: 9.0.8 '@vitejs/plugin-vue': specifier: 5.0.5 - version: 5.0.5(vite@5.2.13(@types/node@20.14.2)(sass@1.77.4)(stylus@0.57.0)(terser@5.31.1))(vue@3.4.27(typescript@5.4.5)) + version: 5.0.5(vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(stylus@0.57.0)(terser@5.31.1))(vue@3.4.27(typescript@5.4.5)) '@vue/runtime-core': specifier: 3.4.27 version: 3.4.27 @@ -702,8 +702,8 @@ importers: specifier: 1.1.2 version: 1.1.2 sass: - specifier: 1.77.4 - version: 1.77.4 + specifier: 1.77.5 + version: 1.77.5 seedrandom: specifier: 3.0.5 version: 3.0.5 @@ -739,10 +739,10 @@ importers: version: 10.0.0 vite: specifier: 5.2.13 - version: 5.2.13(@types/node@20.14.2)(sass@1.77.4)(stylus@0.57.0)(terser@5.31.1) + version: 5.2.13(@types/node@20.14.2)(sass@1.77.5)(stylus@0.57.0)(terser@5.31.1) vite-plugin-compression: specifier: 0.5.1 - version: 0.5.1(vite@5.2.13(@types/node@20.14.2)(sass@1.77.4)(stylus@0.57.0)(terser@5.31.1)) + version: 0.5.1(vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(stylus@0.57.0)(terser@5.31.1)) vue: specifier: 3.4.27 version: 3.4.27(typescript@5.4.5) @@ -931,10 +931,10 @@ importers: version: 6.2.1 vite: specifier: 5.2.13 - version: 5.2.13(@types/node@20.14.2)(sass@1.77.4)(stylus@0.57.0)(terser@5.31.1) + version: 5.2.13(@types/node@20.14.2)(sass@1.77.5)(stylus@0.57.0)(terser@5.31.1) vite-plugin-compression: specifier: 0.5.1 - version: 0.5.1(vite@5.2.13(@types/node@20.14.2)(sass@1.77.4)(stylus@0.57.0)(terser@5.31.1)) + version: 0.5.1(vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(stylus@0.57.0)(terser@5.31.1)) packages: @@ -6892,8 +6892,8 @@ packages: sanitize-html@2.13.0: resolution: {integrity: sha512-Xff91Z+4Mz5QiNSLdLWwjgBDm5b1RU6xBT0+12rapjiaR7SwfRdjw8f+6Rir2MXKLrDicRFHdb51hGOAxmsUIA==} - sass@1.77.4: - resolution: {integrity: sha512-vcF3Ckow6g939GMA4PeU7b2K/9FALXk2KF9J87txdHzXbUF9XRQRwSxcAs/fGaTnJeBFd7UoV22j3lzMLdM0Pw==} + sass@1.77.5: + resolution: {integrity: sha512-oDfX1mukIlxacPdQqNb6mV2tVCrnE+P3nVYioy72V5tlk56CPNcO4TCuFcaCRKKfJ1M3lH95CleRS+dVKL2qMg==} engines: {node: '>=14.0.0'} hasBin: true @@ -10136,9 +10136,9 @@ snapshots: '@ungap/structured-clone@1.2.0': {} - '@vitejs/plugin-vue@5.0.5(vite@5.2.13(@types/node@20.14.2)(sass@1.77.4)(stylus@0.57.0)(terser@5.31.1))(vue@3.4.27(typescript@5.4.5))': + '@vitejs/plugin-vue@5.0.5(vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(stylus@0.57.0)(terser@5.31.1))(vue@3.4.27(typescript@5.4.5))': dependencies: - vite: 5.2.13(@types/node@20.14.2)(sass@1.77.4)(stylus@0.57.0)(terser@5.31.1) + vite: 5.2.13(@types/node@20.14.2)(sass@1.77.5)(stylus@0.57.0)(terser@5.31.1) vue: 3.4.27(typescript@5.4.5) '@volar/language-core@2.3.0': @@ -15081,7 +15081,7 @@ snapshots: parse-srcset: 1.0.2 postcss: 8.4.38 - sass@1.77.4: + sass@1.77.5: dependencies: chokidar: 3.6.0 immutable: 4.3.6 @@ -15939,16 +15939,16 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite-plugin-compression@0.5.1(vite@5.2.13(@types/node@20.14.2)(sass@1.77.4)(stylus@0.57.0)(terser@5.31.1)): + vite-plugin-compression@0.5.1(vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(stylus@0.57.0)(terser@5.31.1)): dependencies: chalk: 4.1.2 debug: 4.3.5 fs-extra: 10.1.0 - vite: 5.2.13(@types/node@20.14.2)(sass@1.77.4)(stylus@0.57.0)(terser@5.31.1) + vite: 5.2.13(@types/node@20.14.2)(sass@1.77.5)(stylus@0.57.0)(terser@5.31.1) transitivePeerDependencies: - supports-color - vite@5.2.13(@types/node@20.14.2)(sass@1.77.4)(stylus@0.57.0)(terser@5.31.1): + vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(stylus@0.57.0)(terser@5.31.1): dependencies: esbuild: 0.20.2 postcss: 8.4.38 @@ -15956,7 +15956,7 @@ snapshots: optionalDependencies: '@types/node': 20.14.2 fsevents: 2.3.3 - sass: 1.77.4 + sass: 1.77.5 stylus: 0.57.0 terser: 5.31.1 From 9f2788888f03e23472209cb4d0710a0927923782 Mon Sep 17 00:00:00 2001 From: CI <project_7_bot_1bfaee5701aed20091a86249a967a6c1@noreply.firefish.dev> Date: Wed, 12 Jun 2024 04:07:06 +0000 Subject: [PATCH 13/16] fix(deps): update dependency bull to v4.13.0 --- packages/backend/package.json | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 7776a1ffaf..06683e0e23 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -40,7 +40,7 @@ "axios": "1.7.2", "backend-rs": "workspace:*", "blurhash": "2.0.5", - "bull": "4.12.9", + "bull": "4.13.0", "cacheable-lookup": "git+https://github.com/TheEssem/cacheable-lookup.git#dd2fb616366a3c68dcf321a57a67295967b204bf", "cbor-x": "1.5.9", "chalk": "5.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 44a24cdd6f..3153a2e544 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -97,8 +97,8 @@ importers: specifier: 2.0.5 version: 2.0.5 bull: - specifier: 4.12.9 - version: 4.12.9 + specifier: 4.13.0 + version: 4.13.0 cacheable-lookup: specifier: git+https://github.com/TheEssem/cacheable-lookup.git#dd2fb616366a3c68dcf321a57a67295967b204bf version: https://codeload.github.com/TheEssem/cacheable-lookup/tar.gz/dd2fb616366a3c68dcf321a57a67295967b204bf @@ -3201,8 +3201,8 @@ packages: builtins@5.1.0: resolution: {integrity: sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==} - bull@4.12.9: - resolution: {integrity: sha512-rqka/O9ZBfrKgI4fanhN6XW0AJ9WYRakjHlCJPjoHyh79xIvEjyU8hvs/CCeRdrbU6zSw8UNfDOjCUaQO1MTuQ==} + bull@4.13.0: + resolution: {integrity: sha512-XAAhHeXtW+luEYuid3shGv25ErmsegrVXMukbP7AqNUgRgiTnRnIGdjPyzmHu3/Tjm6jNdODqLHJ12t07fyUrQ==} engines: {node: '>=12'} busboy@1.6.0: @@ -10735,7 +10735,7 @@ snapshots: dependencies: semver: 7.6.2 - bull@4.12.9: + bull@4.13.0: dependencies: cron-parser: 4.9.0 get-port: 5.1.1 From e60db9e254a04b14f06606007f9da9366ddf0202 Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Wed, 12 Jun 2024 19:43:52 +0900 Subject: [PATCH 14/16] chore (macros-impl): add linebreaks to napi error reason --- packages/macro-rs/macros-impl/src/napi.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/macro-rs/macros-impl/src/napi.rs b/packages/macro-rs/macros-impl/src/napi.rs index 11d9283d5b..13e2242ab8 100644 --- a/packages/macro-rs/macros-impl/src/napi.rs +++ b/packages/macro-rs/macros-impl/src/napi.rs @@ -177,7 +177,9 @@ use quote::{quote, ToTokens}; /// #[napi_derive::napi(js_name = "integerDivide",)] /// pub fn integer_divide_napi(dividend: i64, divisor: i64) -> napi::Result<i64> { /// integer_divide(dividend, divisor) -/// .map_err(|err| napi::Error::from_reason(crate::util::error_chain::format_error(&err))) +/// .map_err(|err| napi::Error::from_reason( +/// format!("\n{}\n", crate::util::error_chain::format_error(&err)) +/// )) /// } /// # }); /// ``` @@ -248,7 +250,9 @@ pub fn napi(macro_attr: TokenStream, item: TokenStream) -> TokenStream { }; // add modifier to function call result function_call_modifiers.push(quote! { - .map_err(|err| napi::Error::from_reason(crate::util::error_chain::format_error(&err))) + .map_err(|err| napi::Error::from_reason( + format!("\n{}\n", crate::util::error_chain::format_error(&err)) + )) }); } }; @@ -382,7 +386,9 @@ crate::macro_unit_tests! { divisor: i64, ) -> napi::Result<i64> { integer_divide(dividend, divisor) - .map_err(|err| napi::Error::from_reason(crate::util::error_chain::format_error(&err))) + .map_err(|err| napi::Error::from_reason( + format!("\n{}\n", crate::util::error_chain::format_error(&err)) + )) } } From 8931bc708ed09c7f21e1e1fb157f37372b76bb5d Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Wed, 12 Jun 2024 20:00:44 +0900 Subject: [PATCH 15/16] test (backend-rs): minor refactoring --- packages/backend-rs/src/util/error_chain.rs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/packages/backend-rs/src/util/error_chain.rs b/packages/backend-rs/src/util/error_chain.rs index 086e5449f2..4d1341dc05 100644 --- a/packages/backend-rs/src/util/error_chain.rs +++ b/packages/backend-rs/src/util/error_chain.rs @@ -70,21 +70,13 @@ mod unit_test { let expected_message_1 = " raw: Error1(InnerError1) message: error 1 occured -caused by: inner error 1 -"; +caused by: inner error 1"; let expected_message_2 = r#" raw: Error2(InnerError2("foo")) message: error 2 occured -caused by: unexpected string 'foo' -"#; +caused by: unexpected string 'foo'"#; - assert_eq!( - error_message_1, - expected_message_1[1..expected_message_1.len() - 1] - ); - assert_eq!( - error_message_2, - expected_message_2[1..expected_message_2.len() - 1] - ); + assert_eq!(error_message_1, expected_message_1[1..]); + assert_eq!(error_message_2, expected_message_2[1..]); } } From 10a1fb33645e7c05b3295f77b5d1cc0e4afed960 Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Wed, 12 Jun 2024 20:12:22 +0900 Subject: [PATCH 16/16] container: rearrange operations for cache efficiency --- Dockerfile | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 789f242070..72c1290e50 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,22 +2,23 @@ FROM docker.io/node:20-alpine as build WORKDIR /firefish +# Copy only backend-rs pnpm-related files first, to cache efficiently +COPY package.json pnpm-workspace.yaml ./ +COPY packages/backend-rs/package.json packages/backend-rs/package.json +COPY packages/backend-rs/npm/linux-x64-musl/package.json packages/backend-rs/npm/linux-x64-musl/package.json +COPY packages/backend-rs/npm/linux-arm64-musl/package.json packages/backend-rs/npm/linux-arm64-musl/package.json + # Install compilation dependencies RUN apk update && apk add --no-cache build-base linux-headers curl ca-certificates python3 perl RUN curl --proto '=https' --tlsv1.2 --silent --show-error --fail https://sh.rustup.rs | sh -s -- -y ENV PATH="/root/.cargo/bin:${PATH}" # Copy only backend-rs dependency-related files first, to cache efficiently -COPY package.json pnpm-workspace.yaml ./ -COPY packages/backend-rs/package.json packages/backend-rs/package.json -COPY packages/backend-rs/npm/linux-x64-musl/package.json packages/backend-rs/npm/linux-x64-musl/package.json -COPY packages/backend-rs/npm/linux-arm64-musl/package.json packages/backend-rs/npm/linux-arm64-musl/package.json - +COPY packages/macro-rs packages/macro-rs/ +COPY packages/backend-rs/src/lib.rs packages/backend-rs/src/ +COPY packages/backend-rs/Cargo.toml packages/backend-rs/Cargo.toml COPY Cargo.toml Cargo.toml COPY Cargo.lock Cargo.lock -COPY packages/backend-rs/Cargo.toml packages/backend-rs/Cargo.toml -COPY packages/backend-rs/src/lib.rs packages/backend-rs/src/ -COPY packages/macro-rs packages/macro-rs/ # Configure pnpm, and install backend-rs dependencies RUN corepack enable && corepack prepare pnpm@latest --activate && pnpm --filter backend-rs install