diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2da723c1020..a3ef11c2786 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: - name: Checkout code uses: actions/checkout@v5 - - name: Setup Node.js 22.x + - name: Setup Node.js 24.x uses: actions/setup-node@v6 with: node-version: 24.x @@ -46,7 +46,7 @@ jobs: - name: Checkout code uses: actions/checkout@v5 - - name: Setup Node.js 22.x + - name: Setup Node.js 24.x uses: actions/setup-node@v6 with: node-version: 24.x @@ -66,7 +66,7 @@ jobs: - name: Checkout code uses: actions/checkout@v5 - - name: Setup Node.js 22.x + - name: Setup Node.js 24.x uses: actions/setup-node@v6 with: node-version: 24.x @@ -92,7 +92,7 @@ jobs: - name: Checkout code uses: actions/checkout@v5 - - name: Setup Node.js 22.x + - name: Setup Node.js 24.x uses: actions/setup-node@v6 with: node-version: 24.x @@ -115,7 +115,7 @@ jobs: - name: Checkout code uses: actions/checkout@v5 - - name: Setup Node.js 22.x + - name: Setup Node.js 24.x uses: actions/setup-node@v6 with: node-version: 24.x @@ -135,7 +135,7 @@ jobs: - name: Checkout code uses: actions/checkout@v5 - - name: Setup Node.js 22.x + - name: Setup Node.js 24.x uses: actions/setup-node@v6 with: node-version: 24.x diff --git a/.github/workflows/codacy.yml b/.github/workflows/codacy.yml new file mode 100644 index 00000000000..3eecb7cf558 --- /dev/null +++ b/.github/workflows/codacy.yml @@ -0,0 +1,63 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +# This workflow checks out code, performs a Codacy security scan +# and integrates the results with the +# GitHub Advanced Security code scanning feature. For more information on +# the Codacy security scan action usage and parameters, see +# https://github.com/codacy/codacy-analysis-cli-action. +# For more information on Codacy Analysis CLI in general, see +# https://github.com/codacy/codacy-analysis-cli. + +name: Codacy Security Scan + +on: + push: + branches: [ "main" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "main" ] + schedule: + - cron: '43 17 * * 0' + +permissions: + contents: read + +jobs: + codacy-security-scan: + permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results + actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status + name: Codacy Security Scan + runs-on: ubuntu-latest + steps: + # Checkout the repository to the GitHub Actions runner + - name: Checkout code + uses: actions/checkout@v5 + + # Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis + - name: Run Codacy Analysis CLI + # Pinned to a specific commit SHA for security; update this SHA when bumping the Codacy action version. + # When updating, look up and note the corresponding release tag for this commit in Codacy's repository. + uses: codacy/codacy-analysis-cli-action@d840f886c4bd4edc059706d09c6a1586111c540b + with: + # Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository + # You can also omit the token and run the tools that support default configurations + project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} + verbose: true + output: results.sarif + format: sarif + # Adjust severity of non-security issues + gh-code-scanning-compat: true + # Force 0 exit code to allow SARIF file generation + # This will hand over control about PR rejection to the GitHub side + max-allowed-issues: 2147483647 + + # Upload the SARIF file generated in the previous step + - name: Upload SARIF results file + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: results.sarif diff --git a/examples/package-lock.json b/examples/package-lock.json index 25e3a4066ba..9861f7237bf 100644 --- a/examples/package-lock.json +++ b/examples/package-lock.json @@ -591,6 +591,7 @@ "version": "8.11.3", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1735,6 +1736,7 @@ "version": "8.57.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -4347,6 +4349,7 @@ "version": "4.13.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.5" }, @@ -5293,6 +5296,7 @@ "version": "5.4.3", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -6930,6 +6934,7 @@ "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -7005,6 +7010,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -8050,7 +8056,8 @@ "version": "0.0.1367902", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1367902.tgz", "integrity": "sha512-XxtPuC3PGakY6PD7dG66/o8KwJ/LkH2/EKe19Dcw58w53dv4/vSQEkn/SzuyhHE2q4zPgCkxQBxus3VV4ql+Pg==", - "dev": true + "dev": true, + "peer": true }, "node_modules/doctrine": { "version": "2.1.0", @@ -8288,6 +8295,7 @@ "integrity": "sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", @@ -9512,10 +9520,11 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -9732,7 +9741,8 @@ "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.33.0.tgz", "integrity": "sha512-VcRWPSLIUEgQJQIE0pVT8FcGBIgFoxz7jtqctE+IiCxWugD0DwgyQBcZBhdSrdMC84eumoqMZsGl2GTreOzwqw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/ms": { "version": "2.1.3", @@ -10077,6 +10087,7 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, + "peer": true, "engines": { "node": ">=12" }, @@ -10258,6 +10269,7 @@ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -10271,6 +10283,7 @@ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -10468,6 +10481,7 @@ "integrity": "sha512-kg6oI4g+vc41vePJyO6dHt/yl0Rz3Thv0kJeVQ3D1kS3E5XSuKbPc29G4IpT/Kv1KQwgHVcN+HtyS+HYLNSvQg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.6" }, @@ -10596,7 +10610,9 @@ } }, "node_modules/serialize-javascript": { - "version": "6.0.1", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { diff --git a/examples/src/examples/animation/blend-trees-2d-cartesian.controls.mjs b/examples/src/examples/animation/blend-trees-2d-cartesian.controls.mjs index 9c85e18d5f1..3bb06b96fd0 100644 --- a/examples/src/examples/animation/blend-trees-2d-cartesian.controls.mjs +++ b/examples/src/examples/animation/blend-trees-2d-cartesian.controls.mjs @@ -124,10 +124,11 @@ export const controls = ({ React, jsx, fragment }) => { componentDidMount() { const { canvas, app } = this; // console.log("componentDidMount()", { canvas, app }); - canvas.addEventListener('mousemove', this.mouseEvent.bind(this)); - canvas.addEventListener('mousedown', this.mouseEvent.bind(this)); - canvas.addEventListener('touchmove', this.mouseEvent.bind(this)); - canvas.addEventListener('touchstart', this.mouseEvent.bind(this)); + this.boundMouseEvent = this.mouseEvent.bind(this); + canvas.addEventListener('mousemove', this.boundMouseEvent); + canvas.addEventListener('mousedown', this.boundMouseEvent); + canvas.addEventListener('touchmove', this.boundMouseEvent); + canvas.addEventListener('touchstart', this.boundMouseEvent); if (!app) { console.warn('no app'); return; @@ -135,6 +136,14 @@ export const controls = ({ React, jsx, fragment }) => { this.onAppStart(); } + componentWillUnmount() { + const { canvas } = this; + canvas.removeEventListener('mousemove', this.boundMouseEvent); + canvas.removeEventListener('mousedown', this.boundMouseEvent); + canvas.removeEventListener('touchmove', this.boundMouseEvent); + canvas.removeEventListener('touchstart', this.boundMouseEvent); + } + render() { return fragment(jsx('canvas', { ref: this.refCanvas })); } diff --git a/examples/src/examples/animation/blend-trees-2d-directional.controls.mjs b/examples/src/examples/animation/blend-trees-2d-directional.controls.mjs index eba5352ef5a..e94617b0688 100644 --- a/examples/src/examples/animation/blend-trees-2d-directional.controls.mjs +++ b/examples/src/examples/animation/blend-trees-2d-directional.controls.mjs @@ -78,6 +78,11 @@ export const controls = ({ React, jsx, fragment }) => { }; canvas.addEventListener('mousemove', mouseEvent); canvas.addEventListener('mousedown', mouseEvent); + + return () => { + canvas.removeEventListener('mousemove', mouseEvent); + canvas.removeEventListener('mousedown', mouseEvent); + }; }); return fragment(jsx('canvas', { ref: canvasRef })); }; diff --git a/package-lock.json b/package-lock.json index 116dcb92553..781198afe17 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3500,9 +3500,9 @@ "optional": true }, "node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, "license": "ISC", "dependencies": { @@ -4420,9 +4420,9 @@ "optional": true }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": {