From 11b0f52880090d267738f62e12c2dbba1320e538 Mon Sep 17 00:00:00 2001 From: kitsne241 <169665926+kitsne241@users.noreply.github.com> Date: Fri, 20 Mar 2026 13:22:32 +0900 Subject: [PATCH 01/11] =?UTF-8?q?=E3=83=90=E3=83=B3=E3=83=89=E3=83=AB?= =?UTF-8?q?=E3=82=A2=E3=83=8A=E3=83=A9=E3=82=A4=E3=82=B6=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/client/package.json | 2 + application/client/webpack.config.js | 4 + application/pnpm-lock.yaml | 145 +++++++++++++++++++++++++-- 3 files changed, 140 insertions(+), 11 deletions(-) diff --git a/application/client/package.json b/application/client/package.json index 9f8e80a6a8..13a16ca567 100644 --- a/application/client/package.json +++ b/application/client/package.json @@ -5,6 +5,7 @@ "license": "MPL-2.0", "author": "CyberAgent, Inc.", "scripts": { + "analyze": "NODE_ENV=development ANALYZE=true webpack", "build": "NODE_ENV=development webpack", "typecheck": "tsc" }, @@ -85,6 +86,7 @@ "react-markdown": "10.1.0", "typescript": "5.9.3", "webpack": "5.102.1", + "webpack-bundle-analyzer": "4.10.2", "webpack-cli": "6.0.1", "webpack-dev-server": "5.2.2" }, diff --git a/application/client/webpack.config.js b/application/client/webpack.config.js index 9fae72647f..91cfebeab0 100644 --- a/application/client/webpack.config.js +++ b/application/client/webpack.config.js @@ -1,6 +1,7 @@ /// const path = require("path"); +const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); const CopyWebpackPlugin = require("copy-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); @@ -94,6 +95,9 @@ const config = { inject: false, template: path.resolve(SRC_PATH, "./index.html"), }), + ...(process.env.ANALYZE === "true" + ? [new BundleAnalyzerPlugin({ analyzerMode: "static", reportFilename: "bundle-report.html", openAnalyzer: false })] + : []), ], resolve: { extensions: [".tsx", ".ts", ".mjs", ".cjs", ".jsx", ".js"], diff --git a/application/pnpm-lock.yaml b/application/pnpm-lock.yaml index 510570f5c9..1572002b24 100644 --- a/application/pnpm-lock.yaml +++ b/application/pnpm-lock.yaml @@ -62,7 +62,7 @@ importers: version: 9.5.0 gifler: specifier: github:themadcreator/gifler#v0.3.0 - version: https://codeload.github.com/themadcreator/gifler/tar.gz/c3259b071c7782f85d4928a5f03d0b378ed003b5 + version: https://codeload.github.com/themadcreator/gifler/tar.gz/89484cb3db174c584a3138e89664f0167a7760c1 image-size: specifier: 2.0.2 version: 2.0.2 @@ -244,9 +244,12 @@ importers: webpack: specifier: 5.102.1 version: 5.102.1(webpack-cli@6.0.1) + webpack-bundle-analyzer: + specifier: 4.10.2 + version: 4.10.2 webpack-cli: specifier: 6.0.1 - version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.102.1) + version: 6.0.1(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.2.2)(webpack@5.102.1) webpack-dev-server: specifier: 5.2.2 version: 5.2.2(webpack-cli@6.0.1)(webpack@5.102.1) @@ -1181,6 +1184,10 @@ packages: peerDependencies: postcss: ^8.4 + '@discoveryjs/json-ext@0.5.7': + resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} + engines: {node: '>=10.0.0'} + '@discoveryjs/json-ext@0.6.3': resolution: {integrity: sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==} engines: {node: '>=14.17.0'} @@ -1608,6 +1615,9 @@ packages: engines: {node: '>=18'} hasBin: true + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + '@tokenizer/inflate@0.4.1': resolution: {integrity: sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==} engines: {node: '>=18'} @@ -1888,6 +1898,10 @@ packages: peerDependencies: acorn: ^8.14.0 + acorn-walk@8.3.5: + resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} + engines: {node: '>=0.4.0'} + acorn@8.15.0: resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} engines: {node: '>=0.4.0'} @@ -2147,6 +2161,10 @@ packages: commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + commander@8.3.0: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} @@ -2293,6 +2311,9 @@ packages: csv-parse@1.3.3: resolution: {integrity: sha512-byxnDBxM1AVF3YfmsK7Smop9/usNz7gAZYSo9eYp61TGcNXraJby1rAiLyJSt1/8Iho2qaxZOtZCOvQMXogPtg==} + debounce@1.2.1: + resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -2395,6 +2416,9 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} @@ -2478,6 +2502,10 @@ packages: escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + escape-string-regexp@5.0.0: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} @@ -2667,8 +2695,8 @@ packages: get-tsconfig@4.13.0: resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} - gifler@https://codeload.github.com/themadcreator/gifler/tar.gz/c3259b071c7782f85d4928a5f03d0b378ed003b5: - resolution: {tarball: https://codeload.github.com/themadcreator/gifler/tar.gz/c3259b071c7782f85d4928a5f03d0b378ed003b5} + gifler@https://codeload.github.com/themadcreator/gifler/tar.gz/89484cb3db174c584a3138e89664f0167a7760c1: + resolution: {tarball: https://codeload.github.com/themadcreator/gifler/tar.gz/89484cb3db174c584a3138e89664f0167a7760c1} version: 0.3.0 github-from-package@0.0.0: @@ -2702,6 +2730,10 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + gzip-size@6.0.0: + resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} + engines: {node: '>=10'} + handle-thing@2.0.1: resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} @@ -2766,6 +2798,9 @@ packages: hpack.js@2.1.6: resolution: {integrity: sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==} + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + html-minifier-terser@6.1.0: resolution: {integrity: sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==} engines: {node: '>=12'} @@ -3384,6 +3419,10 @@ packages: moment@2.30.1: resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -3515,6 +3554,10 @@ packages: resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} engines: {node: '>=18'} + opener@1.5.2: + resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} + hasBin: true + oxfmt@0.36.0: resolution: {integrity: sha512-/ejJ+KoSW6J9bcNT9a9UtJSJNWhJ3yOLSBLbkoFHJs/8CZjmaZVZAJe4YgO1KMJlKpNQasrn/G9JQUEZI3p0EQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -4246,6 +4289,10 @@ packages: simple-get@4.0.1: resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + sirv@2.0.4: + resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} + engines: {node: '>= 10'} + smart-buffer@4.2.0: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} @@ -4419,6 +4466,10 @@ packages: toposort-class@1.0.1: resolution: {integrity: sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==} + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + tree-dump@1.1.0: resolution: {integrity: sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==} engines: {node: '>=10.0'} @@ -4575,6 +4626,11 @@ packages: web-namespaces@2.0.1: resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + webpack-bundle-analyzer@4.10.2: + resolution: {integrity: sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==} + engines: {node: '>= 10.13.0'} + hasBin: true + webpack-cli@6.0.1: resolution: {integrity: sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==} engines: {node: '>=18.12.0'} @@ -4654,6 +4710,18 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + ws@8.18.3: resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} engines: {node: '>=10.0.0'} @@ -5710,6 +5778,8 @@ snapshots: dependencies: postcss: 8.5.6 + '@discoveryjs/json-ext@0.5.7': {} + '@discoveryjs/json-ext@0.6.3': {} '@dr.pogodin/react-helmet@3.0.4(react@19.2.0)': @@ -5972,6 +6042,8 @@ snapshots: dependencies: playwright: 1.50.1 + '@polka/url@1.0.0-next.29': {} + '@tokenizer/inflate@0.4.1': dependencies: debug: 4.4.3 @@ -6260,17 +6332,17 @@ snapshots: '@webpack-cli/configtest@3.0.1(webpack-cli@6.0.1)(webpack@5.102.1)': dependencies: webpack: 5.102.1(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.102.1) + webpack-cli: 6.0.1(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.2.2)(webpack@5.102.1) '@webpack-cli/info@3.0.1(webpack-cli@6.0.1)(webpack@5.102.1)': dependencies: webpack: 5.102.1(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.102.1) + webpack-cli: 6.0.1(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.2.2)(webpack@5.102.1) '@webpack-cli/serve@3.0.1(webpack-cli@6.0.1)(webpack-dev-server@5.2.2)(webpack@5.102.1)': dependencies: webpack: 5.102.1(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.102.1) + webpack-cli: 6.0.1(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.2.2)(webpack@5.102.1) optionalDependencies: webpack-dev-server: 5.2.2(webpack-cli@6.0.1)(webpack@5.102.1) @@ -6295,6 +6367,10 @@ snapshots: dependencies: acorn: 8.15.0 + acorn-walk@8.3.5: + dependencies: + acorn: 8.15.0 + acorn@8.15.0: {} agent-base@6.0.2: @@ -6605,6 +6681,8 @@ snapshots: commander@2.20.3: {} + commander@7.2.0: {} + commander@8.3.0: {} common-tags@1.8.2: {} @@ -6743,6 +6821,8 @@ snapshots: csv-parse@1.3.3: {} + debounce@1.2.1: {} + debug@2.6.9: dependencies: ms: 2.0.0 @@ -6830,6 +6910,8 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + duplexer@0.1.2: {} + ee-first@1.1.1: {} electron-to-chromium@1.5.233: {} @@ -6916,6 +6998,8 @@ snapshots: escape-html@1.0.3: {} + escape-string-regexp@4.0.0: {} + escape-string-regexp@5.0.0: {} eslint-scope@5.1.1: @@ -7161,7 +7245,7 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 - gifler@https://codeload.github.com/themadcreator/gifler/tar.gz/c3259b071c7782f85d4928a5f03d0b378ed003b5: + gifler@https://codeload.github.com/themadcreator/gifler/tar.gz/89484cb3db174c584a3138e89664f0167a7760c1: dependencies: bluebird: 3.7.2 omggif: 1.0.10 @@ -7196,6 +7280,10 @@ snapshots: graceful-fs@4.2.11: {} + gzip-size@6.0.0: + dependencies: + duplexer: 0.1.2 + handle-thing@2.0.1: {} has-flag@4.0.0: {} @@ -7306,6 +7394,8 @@ snapshots: readable-stream: 2.3.8 wbuf: 1.7.3 + html-escaper@2.0.2: {} + html-minifier-terser@6.1.0: dependencies: camel-case: 4.1.2 @@ -8139,6 +8229,8 @@ snapshots: moment@2.30.1: {} + mrmime@2.0.1: {} + ms@2.0.0: {} ms@2.1.3: {} @@ -8277,6 +8369,8 @@ snapshots: is-inside-container: 1.0.0 wsl-utils: 0.1.0 + opener@1.5.2: {} + oxfmt@0.36.0: dependencies: tinypool: 2.1.0 @@ -9191,6 +9285,12 @@ snapshots: once: 1.4.0 simple-concat: 1.0.1 + sirv@2.0.4: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + smart-buffer@4.2.0: optional: true @@ -9393,6 +9493,8 @@ snapshots: toposort-class@1.0.1: {} + totalist@3.0.1: {} + tree-dump@1.1.0(tslib@2.8.1): dependencies: tslib: 2.8.1 @@ -9553,7 +9655,25 @@ snapshots: web-namespaces@2.0.1: {} - webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.102.1): + webpack-bundle-analyzer@4.10.2: + dependencies: + '@discoveryjs/json-ext': 0.5.7 + acorn: 8.15.0 + acorn-walk: 8.3.5 + commander: 7.2.0 + debounce: 1.2.1 + escape-string-regexp: 4.0.0 + gzip-size: 6.0.0 + html-escaper: 2.0.2 + opener: 1.5.2 + picocolors: 1.1.1 + sirv: 2.0.4 + ws: 7.5.10 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + webpack-cli@6.0.1(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.2.2)(webpack@5.102.1): dependencies: '@discoveryjs/json-ext': 0.6.3 '@webpack-cli/configtest': 3.0.1(webpack-cli@6.0.1)(webpack@5.102.1) @@ -9570,6 +9690,7 @@ snapshots: webpack: 5.102.1(webpack-cli@6.0.1) webpack-merge: 6.0.1 optionalDependencies: + webpack-bundle-analyzer: 4.10.2 webpack-dev-server: 5.2.2(webpack-cli@6.0.1)(webpack@5.102.1) webpack-dev-middleware@7.4.5(webpack@5.102.1): @@ -9615,7 +9736,7 @@ snapshots: ws: 8.18.3 optionalDependencies: webpack: 5.102.1(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.102.1) + webpack-cli: 6.0.1(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.2.2)(webpack@5.102.1) transitivePeerDependencies: - bufferutil - debug @@ -9658,7 +9779,7 @@ snapshots: watchpack: 2.4.4 webpack-sources: 3.3.3 optionalDependencies: - webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.102.1) + webpack-cli: 6.0.1(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.2.2)(webpack@5.102.1) transitivePeerDependencies: - '@swc/core' - esbuild @@ -9689,6 +9810,8 @@ snapshots: wrappy@1.0.2: {} + ws@7.5.10: {} + ws@8.18.3: {} wsl-utils@0.1.0: From 97cf1dd01b00279cc1d4671c93449f60017765d5 Mon Sep 17 00:00:00 2001 From: kitsne241 <169665926+kitsne241@users.noreply.github.com> Date: Fri, 20 Mar 2026 15:00:11 +0900 Subject: [PATCH 02/11] =?UTF-8?q?wasm=20=E3=83=90=E3=82=A4=E3=83=8A?= =?UTF-8?q?=E3=83=AA=E3=82=92=E5=BF=85=E8=A6=81=E3=81=AB=E5=BF=9C=E3=81=98?= =?UTF-8?q?=E3=81=A6=E8=AA=AD=E3=81=BF=E8=BE=BC=E3=82=80=E3=81=93=E3=81=A8?= =?UTF-8?q?=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/client/src/utils/convert_image.ts | 3 +-- application/client/src/utils/load_ffmpeg.ts | 8 ++---- application/client/webpack.config.js | 27 +++++++++---------- 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/application/client/src/utils/convert_image.ts b/application/client/src/utils/convert_image.ts index 9fce086d9c..1c4584ca74 100644 --- a/application/client/src/utils/convert_image.ts +++ b/application/client/src/utils/convert_image.ts @@ -1,5 +1,4 @@ import { initializeImageMagick, ImageMagick, MagickFormat } from "@imagemagick/magick-wasm"; -import magickWasm from "@imagemagick/magick-wasm/magick.wasm?binary"; import { dump, insert, ImageIFD } from "piexifjs"; interface Options { @@ -7,7 +6,7 @@ interface Options { } export async function convertImage(file: File, options: Options): Promise { - await initializeImageMagick(magickWasm); + await initializeImageMagick(new URL("/static/magick.wasm", location.origin)); const byteArray = new Uint8Array(await file.arrayBuffer()); diff --git a/application/client/src/utils/load_ffmpeg.ts b/application/client/src/utils/load_ffmpeg.ts index f923a3d5a4..985c7ed952 100644 --- a/application/client/src/utils/load_ffmpeg.ts +++ b/application/client/src/utils/load_ffmpeg.ts @@ -4,12 +4,8 @@ export async function loadFFmpeg(): Promise { const ffmpeg = new FFmpeg(); await ffmpeg.load({ - coreURL: await import("@ffmpeg/core?binary").then(({ default: b }) => { - return URL.createObjectURL(new Blob([b], { type: "text/javascript" })); - }), - wasmURL: await import("@ffmpeg/core/wasm?binary").then(({ default: b }) => { - return URL.createObjectURL(new Blob([b], { type: "application/wasm" })); - }), + coreURL: "/static/ffmpeg-core.js", + wasmURL: "/static/ffmpeg-core.wasm", }); return ffmpeg; diff --git a/application/client/webpack.config.js b/application/client/webpack.config.js index 91cfebeab0..2464d97001 100644 --- a/application/client/webpack.config.js +++ b/application/client/webpack.config.js @@ -89,6 +89,18 @@ const config = { from: path.resolve(__dirname, "node_modules/katex/dist/fonts"), to: path.resolve(DIST_PATH, "styles/fonts"), }, + { + from: path.resolve(__dirname, "node_modules/@ffmpeg/core/dist/umd/ffmpeg-core.js"), + to: path.resolve(DIST_PATH, "static/ffmpeg-core.js"), + }, + { + from: path.resolve(__dirname, "node_modules/@ffmpeg/core/dist/umd/ffmpeg-core.wasm"), + to: path.resolve(DIST_PATH, "static/ffmpeg-core.wasm"), + }, + { + from: path.resolve(__dirname, "node_modules/@imagemagick/magick-wasm/dist/magick.wasm"), + to: path.resolve(DIST_PATH, "static/magick.wasm"), + }, ], }), new HtmlWebpackPlugin({ @@ -109,21 +121,6 @@ const config = { "node_modules", "@ffmpeg/ffmpeg/dist/esm/index.js", ), - "@ffmpeg/core$": path.resolve( - __dirname, - "node_modules", - "@ffmpeg/core/dist/umd/ffmpeg-core.js", - ), - "@ffmpeg/core/wasm$": path.resolve( - __dirname, - "node_modules", - "@ffmpeg/core/dist/umd/ffmpeg-core.wasm", - ), - "@imagemagick/magick-wasm/magick.wasm$": path.resolve( - __dirname, - "node_modules", - "@imagemagick/magick-wasm/dist/magick.wasm", - ), }, fallback: { fs: false, From 4c600a96c9b70fe7189eb272ad72beb07ca745cf Mon Sep 17 00:00:00 2001 From: kitsne241 <169665926+kitsne241@users.noreply.github.com> Date: Fri, 20 Mar 2026 16:54:06 +0900 Subject: [PATCH 03/11] =?UTF-8?q?=E7=94=BB=E5=83=8F=E3=82=92=E7=9B=B4src?= =?UTF-8?q?=E3=81=A7=E8=AA=AD=E3=81=BF=E8=BE=BC=E3=81=BF=20&=20alt=20?= =?UTF-8?q?=E3=82=92=20API=20=E3=81=A7=E5=8F=96=E5=BE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/foundation/CoveredImage.tsx | 53 +++---------------- .../client/src/components/post/ImageArea.tsx | 2 +- application/server/src/routes/static.ts | 30 +++-------- 3 files changed, 13 insertions(+), 72 deletions(-) diff --git a/application/client/src/components/foundation/CoveredImage.tsx b/application/client/src/components/foundation/CoveredImage.tsx index 8ad9cc1f7d..445438df13 100644 --- a/application/client/src/components/foundation/CoveredImage.tsx +++ b/application/client/src/components/foundation/CoveredImage.tsx @@ -1,70 +1,29 @@ -import classNames from "classnames"; -import sizeOf from "image-size"; -import { load, ImageIFD } from "piexifjs"; -import { MouseEvent, RefCallback, useCallback, useId, useMemo, useState } from "react"; +import { MouseEvent, useCallback, useId } from "react"; import { Button } from "@web-speed-hackathon-2026/client/src/components/foundation/Button"; import { Modal } from "@web-speed-hackathon-2026/client/src/components/modal/Modal"; -import { useFetch } from "@web-speed-hackathon-2026/client/src/hooks/use_fetch"; -import { fetchBinary } from "@web-speed-hackathon-2026/client/src/utils/fetchers"; interface Props { + alt: string; src: string; } /** * アスペクト比を維持したまま、要素のコンテンツボックス全体を埋めるように画像を拡大縮小します */ -export const CoveredImage = ({ src }: Props) => { +export const CoveredImage = ({ alt, src }: Props) => { const dialogId = useId(); // ダイアログの背景をクリックしたときに投稿詳細ページに遷移しないようにする const handleDialogClick = useCallback((ev: MouseEvent) => { ev.stopPropagation(); }, []); - const { data, isLoading } = useFetch(src, fetchBinary); - - const imageSize = useMemo(() => { - return data != null ? sizeOf(Buffer.from(data)) : { height: 0, width: 0 }; - }, [data]); - - const alt = useMemo(() => { - const exif = data != null ? load(Buffer.from(data).toString("binary")) : null; - const raw = exif?.["0th"]?.[ImageIFD.ImageDescription]; - return raw != null ? new TextDecoder().decode(Buffer.from(raw, "binary")) : ""; - }, [data]); - - const blobUrl = useMemo(() => { - return data != null ? URL.createObjectURL(new Blob([data])) : null; - }, [data]); - - const [containerSize, setContainerSize] = useState({ height: 0, width: 0 }); - const callbackRef = useCallback>((el) => { - setContainerSize({ - height: el?.clientHeight ?? 0, - width: el?.clientWidth ?? 0, - }); - }, []); - - if (isLoading || data === null || blobUrl === null) { - return null; - } - - const containerRatio = containerSize.height / containerSize.width; - const imageRatio = imageSize?.height / imageSize?.width; - return ( -
+
{alt} imageRatio, - "w-full h-auto": containerRatio <= imageRatio, - }, - )} - src={blobUrl} + className="h-full w-full object-cover" + src={src} />
); })} diff --git a/application/server/src/routes/static.ts b/application/server/src/routes/static.ts index b5820c986e..9296b8d3b2 100644 --- a/application/server/src/routes/static.ts +++ b/application/server/src/routes/static.ts @@ -2,34 +2,16 @@ import history from "connect-history-api-fallback"; import { Router } from "express"; import serveStatic from "serve-static"; -import { - CLIENT_DIST_PATH, - PUBLIC_PATH, - UPLOAD_PATH, -} from "@web-speed-hackathon-2026/server/src/paths"; +import { CLIENT_DIST_PATH, PUBLIC_PATH, UPLOAD_PATH } from "@web-speed-hackathon-2026/server/src/paths"; export const staticRouter = Router(); -// SPA 対応のため、ファイルが存在しないときに index.html を返す +// 拡張子がついてるリクエストは index.html に書き換えて CLIENT_DIST_PATH に引っかける +// ついてないリクエストはそのまま通して他のルーターに引っかける staticRouter.use(history()); -staticRouter.use( - serveStatic(UPLOAD_PATH, { - etag: false, - lastModified: false, - }), -); +staticRouter.use(serveStatic(UPLOAD_PATH)); -staticRouter.use( - serveStatic(PUBLIC_PATH, { - etag: false, - lastModified: false, - }), -); +staticRouter.use(serveStatic(PUBLIC_PATH)); -staticRouter.use( - serveStatic(CLIENT_DIST_PATH, { - etag: false, - lastModified: false, - }), -); +staticRouter.use(serveStatic(CLIENT_DIST_PATH)); From 34ab60f5a757a54630e610a57ae27a4b8d9c76d4 Mon Sep 17 00:00:00 2001 From: kitsne241 <169665926+kitsne241@users.noreply.github.com> Date: Fri, 20 Mar 2026 18:12:34 +0900 Subject: [PATCH 04/11] =?UTF-8?q?=E7=94=BB=E5=83=8F=E3=81=AE=20Cache-Contr?= =?UTF-8?q?ol=20=E3=82=92=E4=B8=8D=E5=A4=89=E3=81=AB=E8=A8=AD=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/server/package.json | 1 + application/server/pnpm-lock.yaml | 315 ++++++++++++++++++++++++ application/server/src/routes/static.ts | 37 ++- 3 files changed, 351 insertions(+), 2 deletions(-) create mode 100644 application/server/pnpm-lock.yaml diff --git a/application/server/package.json b/application/server/package.json index 9482575df7..155632ed62 100644 --- a/application/server/package.json +++ b/application/server/package.json @@ -25,6 +25,7 @@ "music-metadata": "11.10.3", "sequelize": "6.37.7", "serve-static": "2.2.0", + "sharp": "^0.34.5", "sqlite3": "5.1.7", "tsx": "4.20.6", "uuid": "13.0.0", diff --git a/application/server/pnpm-lock.yaml b/application/server/pnpm-lock.yaml new file mode 100644 index 0000000000..8a54e70d33 --- /dev/null +++ b/application/server/pnpm-lock.yaml @@ -0,0 +1,315 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@web-speed-hackathon-2026/server': + specifier: workspace:* + version: 'link:' + sharp: + specifier: ^0.34.5 + version: 0.34.5 + +packages: + + '@emnapi/runtime@1.9.1': + resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==} + + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + +snapshots: + + '@emnapi/runtime@1.9.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@img/colour@1.1.0': {} + + '@img/sharp-darwin-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.2.4 + optional: true + + '@img/sharp-darwin-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.2.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.2.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 + optional: true + + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 + optional: true + + '@img/sharp-linux-ppc64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.2.4 + optional: true + + '@img/sharp-linux-riscv64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.2.4 + optional: true + + '@img/sharp-linux-s390x@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.4 + optional: true + + '@img/sharp-linux-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + optional: true + + '@img/sharp-wasm32@0.34.5': + dependencies: + '@emnapi/runtime': 1.9.1 + optional: true + + '@img/sharp-win32-arm64@0.34.5': + optional: true + + '@img/sharp-win32-ia32@0.34.5': + optional: true + + '@img/sharp-win32-x64@0.34.5': + optional: true + + detect-libc@2.1.2: {} + + semver@7.7.4: {} + + sharp@0.34.5: + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.7.4 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 + + tslib@2.8.1: + optional: true diff --git a/application/server/src/routes/static.ts b/application/server/src/routes/static.ts index 9296b8d3b2..2691413aad 100644 --- a/application/server/src/routes/static.ts +++ b/application/server/src/routes/static.ts @@ -1,15 +1,48 @@ +import { promises as fs } from "fs"; +import path from "path"; + import history from "connect-history-api-fallback"; import { Router } from "express"; +import sharp from "sharp"; import serveStatic from "serve-static"; import { CLIENT_DIST_PATH, PUBLIC_PATH, UPLOAD_PATH } from "@web-speed-hackathon-2026/server/src/paths"; export const staticRouter = Router(); -// 拡張子がついてるリクエストは index.html に書き換えて CLIENT_DIST_PATH に引っかける -// ついてないリクエストはそのまま通して他のルーターに引っかける +// SPA 対応のため、ファイルが存在しないときに index.html を返す staticRouter.use(history()); +const IMAGE_CACHE_PATH = path.resolve(UPLOAD_PATH, "cache/images"); + +staticRouter.get("/images/*relativePath", async (req, res, next) => { + const relativePath = (req.params as Record)["relativePath"]; + if (relativePath === undefined) return next(); + const originalPath = path.resolve(UPLOAD_PATH, "images", relativePath); + + try { + await fs.access(originalPath); + } catch { + return next(); + } + + const cachedPath = path.resolve(IMAGE_CACHE_PATH, relativePath.replace(/\.jpg$/, ".webp")); + + try { + await fs.access(cachedPath); + } catch { + await fs.mkdir(path.dirname(cachedPath), { recursive: true }); + await sharp(originalPath) + .resize({ width: 800, withoutEnlargement: true }) + .webp({ quality: 80 }) + .toFile(cachedPath); + } + + res.setHeader("Content-Type", "image/webp"); + res.setHeader("Cache-Control", "max-age=31536000, immutable"); + return res.sendFile(cachedPath); +}); + staticRouter.use(serveStatic(UPLOAD_PATH)); staticRouter.use(serveStatic(PUBLIC_PATH)); From 1671d761a994db4220b3ba017df5843e08bca153 Mon Sep 17 00:00:00 2001 From: kitsne241 <169665926+kitsne241@users.noreply.github.com> Date: Fri, 20 Mar 2026 18:16:17 +0900 Subject: [PATCH 05/11] =?UTF-8?q?=E4=B8=8D=E5=85=B7=E5=90=88=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/server/src/routes/static.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/application/server/src/routes/static.ts b/application/server/src/routes/static.ts index 2691413aad..9c91012131 100644 --- a/application/server/src/routes/static.ts +++ b/application/server/src/routes/static.ts @@ -16,8 +16,9 @@ staticRouter.use(history()); const IMAGE_CACHE_PATH = path.resolve(UPLOAD_PATH, "cache/images"); staticRouter.get("/images/*relativePath", async (req, res, next) => { - const relativePath = (req.params as Record)["relativePath"]; - if (relativePath === undefined) return next(); + const relativePathParam = (req.params as Record)["relativePath"]; + if (relativePathParam === undefined) return next(); + const relativePath = Array.isArray(relativePathParam) ? relativePathParam.join("/") : relativePathParam; const originalPath = path.resolve(UPLOAD_PATH, "images", relativePath); try { From eb24d75d0deb5bf78f09645e867cb71be6255249 Mon Sep 17 00:00:00 2001 From: kitsne241 <169665926+kitsne241@users.noreply.github.com> Date: Fri, 20 Mar 2026 22:27:17 +0900 Subject: [PATCH 06/11] =?UTF-8?q?=E3=83=90=E3=82=A4=E3=83=8A=E3=83=AA?= =?UTF-8?q?=E3=81=AE=E9=9D=9E=E5=90=8C=E6=9C=9F=E8=AA=AD=E3=81=BF=E8=BE=BC?= =?UTF-8?q?=E3=81=BF=E3=81=A8=E3=82=B9=E3=82=AF=E3=83=AD=E3=83=BC=E3=83=AB?= =?UTF-8?q?=E3=83=8F=E3=83=B3=E3=83=89=E3=83=AA=E3=83=B3=E3=82=B0=E3=81=AE?= =?UTF-8?q?=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/foundation/InfiniteScroll.tsx | 15 +++++++-------- .../client/src/hooks/use_infinite_fetch.ts | 12 +++++------- application/client/src/utils/fetchers.ts | 4 ---- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/application/client/src/components/foundation/InfiniteScroll.tsx b/application/client/src/components/foundation/InfiniteScroll.tsx index 408f24c107..dc4ba43207 100644 --- a/application/client/src/components/foundation/InfiniteScroll.tsx +++ b/application/client/src/components/foundation/InfiniteScroll.tsx @@ -13,10 +13,7 @@ export const InfiniteScroll = ({ children, fetchMore, items }: Props) => { useEffect(() => { const handler = () => { - // 念の為 2の18乗 回、最下部かどうかを確認する - const hasReached = Array.from(Array(2 ** 18), () => { - return window.innerHeight + Math.ceil(window.scrollY) >= document.body.offsetHeight; - }).every(Boolean); + const hasReached = window.innerHeight + Math.ceil(window.scrollY) >= document.body.offsetHeight; // 画面最下部にスクロールしたタイミングで、登録したハンドラを呼び出す if (hasReached && !prevReachedRef.current) { @@ -33,10 +30,12 @@ export const InfiniteScroll = ({ children, fetchMore, items }: Props) => { prevReachedRef.current = false; handler(); - document.addEventListener("wheel", handler, { passive: false }); - document.addEventListener("touchmove", handler, { passive: false }); - document.addEventListener("resize", handler, { passive: false }); - document.addEventListener("scroll", handler, { passive: false }); + // passive: false はブラウザに「このハンドラが preventDefault() を呼ぶかもしれない」と伝えるフラグ + // ブラウザがスクロールを遅延させてハンドラの完了を待つ原因になる + document.addEventListener("wheel", handler, { passive: true }); + document.addEventListener("touchmove", handler, { passive: true }); + document.addEventListener("resize", handler, { passive: true }); + document.addEventListener("scroll", handler, { passive: true }); return () => { document.removeEventListener("wheel", handler); document.removeEventListener("touchmove", handler); diff --git a/application/client/src/hooks/use_infinite_fetch.ts b/application/client/src/hooks/use_infinite_fetch.ts index 394fccd9ea..9612fe2c76 100644 --- a/application/client/src/hooks/use_infinite_fetch.ts +++ b/application/client/src/hooks/use_infinite_fetch.ts @@ -9,10 +9,7 @@ interface ReturnValues { fetchMore: () => void; } -export function useInfiniteFetch( - apiPath: string, - fetcher: (apiPath: string) => Promise, -): ReturnValues { +export function useInfiniteFetch(apiPath: string, fetcher: (apiPath: string) => Promise): ReturnValues { const internalRef = useRef({ isLoading: false, offset: 0 }); const [result, setResult] = useState, "fetchMore">>({ @@ -36,11 +33,12 @@ export function useInfiniteFetch( offset, }; - void fetcher(apiPath).then( - (allData) => { + const separator = apiPath.includes("?") ? "&" : "?"; + void fetcher(`${apiPath}${separator}limit=${LIMIT}&offset=${offset}`).then( + (pageData) => { setResult((cur) => ({ ...cur, - data: [...cur.data, ...allData.slice(offset, offset + LIMIT)], + data: [...cur.data, ...pageData], isLoading: false, })); internalRef.current = { diff --git a/application/client/src/utils/fetchers.ts b/application/client/src/utils/fetchers.ts index 92a14f408f..c4615071b6 100644 --- a/application/client/src/utils/fetchers.ts +++ b/application/client/src/utils/fetchers.ts @@ -3,7 +3,6 @@ import { gzip } from "pako"; export async function fetchBinary(url: string): Promise { const result = await $.ajax({ - async: false, dataType: "binary", method: "GET", responseType: "arraybuffer", @@ -14,7 +13,6 @@ export async function fetchBinary(url: string): Promise { export async function fetchJSON(url: string): Promise { const result = await $.ajax({ - async: false, dataType: "json", method: "GET", url, @@ -24,7 +22,6 @@ export async function fetchJSON(url: string): Promise { export async function sendFile(url: string, file: File): Promise { const result = await $.ajax({ - async: false, data: file, dataType: "json", headers: { @@ -43,7 +40,6 @@ export async function sendJSON(url: string, data: object): Promise { const compressed = gzip(uint8Array); const result = await $.ajax({ - async: false, data: compressed, dataType: "json", headers: { From 6c0ea88472874bdceff2b1b689f495be106059f4 Mon Sep 17 00:00:00 2001 From: kitsne241 <169665926+kitsne241@users.noreply.github.com> Date: Fri, 20 Mar 2026 23:00:29 +0900 Subject: [PATCH 07/11] =?UTF-8?q?ReDoS=20=E3=82=92=E8=A7=A3=E6=B6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/client/src/search/services.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/application/client/src/search/services.ts b/application/client/src/search/services.ts index 77f9de5de9..e8713b9bb0 100644 --- a/application/client/src/search/services.ts +++ b/application/client/src/search/services.ts @@ -10,8 +10,8 @@ export const sanitizeSearchText = (input: string): string => { }; export const parseSearchQuery = (query: string) => { - const sincePattern = /since:((\d|\d\d|\d\d\d\d-\d\d-\d\d)+)+$/; - const untilPattern = /until:((\d|\d\d|\d\d\d\d-\d\d-\d\d)+)+$/; + const sincePattern = /since:(\d{4}-\d{2}-\d{2})/; + const untilPattern = /until:(\d{4}-\d{2}-\d{2})/; const sincePart = query.match(/since:[^\s]*/)?.[0] || ""; const untilPart = query.match(/until:[^\s]*/)?.[0] || ""; @@ -38,7 +38,7 @@ export const parseSearchQuery = (query: string) => { }; export const isValidDate = (dateStr: string): boolean => { - const slowDateLike = /^(\d+)+-(\d+)+-(\d+)+$/; + const slowDateLike = /^\d+-\d+-\d+$/; if (!slowDateLike.test(dateStr)) return false; const date = new Date(dateStr); From 9bd3211ec3df0883c6e841a07f686e4fcf6c170b Mon Sep 17 00:00:00 2001 From: kitsne241 <169665926+kitsne241@users.noreply.github.com> Date: Sat, 21 Mar 2026 15:22:17 +0900 Subject: [PATCH 08/11] =?UTF-8?q?DM=E8=A9=B3=E7=B4=B0=E3=83=9A=E3=83=BC?= =?UTF-8?q?=E3=82=B8=E3=83=BBCrok=20AI=E3=83=81=E3=83=A3=E3=83=83=E3=83=88?= =?UTF-8?q?=E3=82=92=E9=80=9A=E3=81=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/client/src/containers/AuthModalContainer.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/application/client/src/containers/AuthModalContainer.tsx b/application/client/src/containers/AuthModalContainer.tsx index 8d159f3528..3d466c4566 100644 --- a/application/client/src/containers/AuthModalContainer.tsx +++ b/application/client/src/containers/AuthModalContainer.tsx @@ -43,8 +43,10 @@ export const AuthModalContainer = ({ id, onUpdateActiveUser }: Props) => { const element = ref.current; const handleToggle = () => { - // モーダル開閉時にkeyを更新することでフォームの状態をリセットする - setResetKey((key) => key + 1); + // ダイアログが閉じた時だけフォームをリセット(開いた時はリセットしない) + if (!element.open) { + setResetKey((key) => key + 1); + } }; element.addEventListener("toggle", handleToggle); return () => { From fafeede244566534adc27ff0c8da21a3810dd5c0 Mon Sep 17 00:00:00 2001 From: kitsne241 <169665926+kitsne241@users.noreply.github.com> Date: Sat, 21 Mar 2026 15:35:47 +0900 Subject: [PATCH 09/11] =?UTF-8?q?=E3=83=91=E3=82=B9=E3=83=AF=E3=83=BC?= =?UTF-8?q?=E3=83=89=E3=81=A7=E3=82=82=20ReDos=20=E3=82=92=E7=99=BA?= =?UTF-8?q?=E8=A6=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/client/src/auth/validation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/client/src/auth/validation.ts b/application/client/src/auth/validation.ts index 2a83bbfb15..12425260af 100644 --- a/application/client/src/auth/validation.ts +++ b/application/client/src/auth/validation.ts @@ -13,7 +13,7 @@ export const validate = (values: AuthFormData): FormErrors => { errors.name = "名前を入力してください"; } - if (/^(?:[^\P{Letter}&&\P{Number}]*){16,}$/v.test(normalizedPassword)) { + if (/^[\p{Letter}\p{Number}]+$/v.test(normalizedPassword)) { errors.password = "パスワードには記号を含める必要があります"; } if (normalizedPassword.length === 0) { From faea7e04185bcdc6f65688fa096583bd6e33d376 Mon Sep 17 00:00:00 2001 From: kitsne241 <169665926+kitsne241@users.noreply.github.com> Date: Sat, 21 Mar 2026 17:18:34 +0900 Subject: [PATCH 10/11] =?UTF-8?q?pnpm-lock=20=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/pnpm-lock.yaml | 295 +++++++++++++++++++++++++++++++++++++ 1 file changed, 295 insertions(+) diff --git a/application/pnpm-lock.yaml b/application/pnpm-lock.yaml index 1572002b24..6e721a40f8 100644 --- a/application/pnpm-lock.yaml +++ b/application/pnpm-lock.yaml @@ -304,6 +304,9 @@ importers: serve-static: specifier: 2.2.0 version: 2.2.0 + sharp: + specifier: ^0.34.5 + version: 0.34.5 sqlite3: specifier: 5.1.7 version: 5.1.7 @@ -1197,6 +1200,9 @@ packages: peerDependencies: react: '19' + '@emnapi/runtime@1.9.1': + resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==} + '@esbuild/aix-ppc64@0.25.11': resolution: {integrity: sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==} engines: {node: '>=18'} @@ -1375,6 +1381,159 @@ packages: '@imagemagick/magick-wasm@0.0.37': resolution: {integrity: sha512-tVs9hcWu9u7I3Jz/XvUYVvCEniuxAR+JjZEzI+yKtQmYAtNsLF1WjoH1HZGCKPumaB9jAHZlcf2RGT9+1l3nxQ==} + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -4252,6 +4411,10 @@ packages: resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} engines: {node: '>=8'} + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -5787,6 +5950,11 @@ snapshots: '@babel/runtime': 7.28.4 react: 19.2.0 + '@emnapi/runtime@1.9.1': + dependencies: + tslib: 2.8.1 + optional: true + '@esbuild/aix-ppc64@0.25.11': optional: true @@ -5880,6 +6048,102 @@ snapshots: '@imagemagick/magick-wasm@0.0.37': {} + '@img/colour@1.1.0': {} + + '@img/sharp-darwin-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.2.4 + optional: true + + '@img/sharp-darwin-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.2.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.2.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 + optional: true + + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 + optional: true + + '@img/sharp-linux-ppc64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.2.4 + optional: true + + '@img/sharp-linux-riscv64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.2.4 + optional: true + + '@img/sharp-linux-s390x@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.4 + optional: true + + '@img/sharp-linux-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + optional: true + + '@img/sharp-wasm32@0.34.5': + dependencies: + '@emnapi/runtime': 1.9.1 + optional: true + + '@img/sharp-win32-arm64@0.34.5': + optional: true + + '@img/sharp-win32-ia32@0.34.5': + optional: true + + '@img/sharp-win32-x64@0.34.5': + optional: true + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -9238,6 +9502,37 @@ snapshots: dependencies: kind-of: 6.0.3 + sharp@0.34.5: + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.7.3 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 From ba5421f5084638727285933e760626fe0f903cec Mon Sep 17 00:00:00 2001 From: kitsne241 <169665926+kitsne241@users.noreply.github.com> Date: Sat, 21 Mar 2026 18:29:19 +0900 Subject: [PATCH 11/11] =?UTF-8?q?=E6=9C=80=E7=B5=82=E6=8F=90=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/containers/AuthModalContainer.tsx | 6 +----- application/server/src/app.ts | 4 ++++ application/server/src/routes/api/auth.ts | 8 +++++++- scoring-tool/signin-failure.png | Bin 0 -> 106120 bytes .../scoring/calculate_user_auth_flow_action.ts | 8 ++++++++ 5 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 scoring-tool/signin-failure.png diff --git a/application/client/src/containers/AuthModalContainer.tsx b/application/client/src/containers/AuthModalContainer.tsx index 3d466c4566..5cdddb699e 100644 --- a/application/client/src/containers/AuthModalContainer.tsx +++ b/application/client/src/containers/AuthModalContainer.tsx @@ -81,11 +81,7 @@ export const AuthModalContainer = ({ id, onUpdateActiveUser }: Props) => { return ( - + ); }; diff --git a/application/server/src/app.ts b/application/server/src/app.ts index 671fb424cc..7244eb0dc4 100644 --- a/application/server/src/app.ts +++ b/application/server/src/app.ts @@ -21,5 +21,9 @@ app.use((_req, res, next) => { return next(); }); +app.use((req, _res, next) => { + console.log(`[req] ${req.method} ${req.url} content-type=${req.headers["content-type"]} content-encoding=${req.headers["content-encoding"]}`); + next(); +}); app.use("/api/v1", apiRouter); app.use(staticRouter); diff --git a/application/server/src/routes/api/auth.ts b/application/server/src/routes/api/auth.ts index f313e87bbb..0a0c5f3a66 100644 --- a/application/server/src/routes/api/auth.ts +++ b/application/server/src/routes/api/auth.ts @@ -25,20 +25,26 @@ authRouter.post("/signup", async (req, res) => { }); authRouter.post("/signin", async (req, res) => { + console.log("[signin] body:", req.body); const user = await User.findOne({ where: { username: req.body.username, }, }); + console.log("[signin] user found:", user?.username ?? null); if (user === null) { + console.log("[signin] user not found"); throw new httpErrors.BadRequest(); } - if (!user.validPassword(req.body.password)) { + const valid = user.validPassword(req.body.password); + console.log("[signin] password valid:", valid); + if (!valid) { throw new httpErrors.BadRequest(); } req.session.userId = user.id; + console.log("[signin] success"); return res.status(200).type("application/json").send(user); }); diff --git a/scoring-tool/signin-failure.png b/scoring-tool/signin-failure.png new file mode 100644 index 0000000000000000000000000000000000000000..4bb9866eea7d1058d83cc3d8cb4de1b4d19a5d78 GIT binary patch literal 106120 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 N(?=Q)3m%xg`WHhwZNmTn literal 0 HcmV?d00001 diff --git a/scoring-tool/src/scoring/calculate_user_auth_flow_action.ts b/scoring-tool/src/scoring/calculate_user_auth_flow_action.ts index da1858e3b0..f2d31554a1 100644 --- a/scoring-tool/src/scoring/calculate_user_auth_flow_action.ts +++ b/scoring-tool/src/scoring/calculate_user_auth_flow_action.ts @@ -126,13 +126,21 @@ export async function calculateUserAuthFlowAction({ } catch (err) { throw new Error("パスワードの入力に失敗しました", { cause: err }); } + const signinRequests: string[] = []; + playwrightPage.on("request", (req) => { + if (req.url().includes("/api/")) signinRequests.push(`${req.method()} ${req.url()}`); + }); try { const button = playwrightPage.getByRole("dialog").getByRole("button", { name: "サインイン" }); + const isDisabled = await button.isDisabled(); + console.log("[debug] signin button disabled:", isDisabled); await button.click(); await playwrightPage .getByRole("link", { name: "マイページ" }) .waitFor({ timeout: 10 * 1000 }); } catch (err) { + console.log("[debug] requests made:", signinRequests); + await playwrightPage.screenshot({ path: "signin-failure.png" }); throw new Error("サインインに失敗しました", { cause: err }); } }