From 471280d811cbb593c6b6afaff24d845cc8f49efa Mon Sep 17 00:00:00 2001 From: Brian Tedder Date: Wed, 15 Jan 2025 16:58:17 -0600 Subject: [PATCH 1/4] (fix) proxy function props to prevent stale state in callbacks (#604) * proxy props to prevent callback stale closures * fix: rollup config for tsx tests * split tsconfig * update @playwright/test --- .changeset/polite-snakes-enjoy.md | 5 + package-lock.json | 490 +++++++++++++----- packages/react-paypal-js/.storybook/main.js | 2 +- packages/react-paypal-js/jest.setup.ts | 1 + packages/react-paypal-js/package.json | 11 +- packages/react-paypal-js/rollup.config.js | 9 +- .../src/components/PayPalButtons.test.tsx | 65 ++- .../src/components/PayPalButtons.tsx | 4 +- .../src/hooks/useProxyProps.test.ts | 57 ++ .../src/hooks/useProxyProps.ts | 31 ++ .../payPalButtons/PayPalButtons.stories.tsx | 57 +- packages/react-paypal-js/tsconfig.json | 11 +- packages/react-paypal-js/tsconfig.lib.json | 8 + packages/react-paypal-js/tsconfig.test.json | 4 + 14 files changed, 614 insertions(+), 141 deletions(-) create mode 100644 .changeset/polite-snakes-enjoy.md create mode 100644 packages/react-paypal-js/jest.setup.ts create mode 100644 packages/react-paypal-js/src/hooks/useProxyProps.test.ts create mode 100644 packages/react-paypal-js/src/hooks/useProxyProps.ts create mode 100644 packages/react-paypal-js/tsconfig.lib.json create mode 100644 packages/react-paypal-js/tsconfig.test.json diff --git a/.changeset/polite-snakes-enjoy.md b/.changeset/polite-snakes-enjoy.md new file mode 100644 index 00000000..657ae9c0 --- /dev/null +++ b/.changeset/polite-snakes-enjoy.md @@ -0,0 +1,5 @@ +--- +"@paypal/react-paypal-js": minor +--- + +(fix) proxy props to prevent stale closure diff --git a/package-lock.json b/package-lock.json index 6f49e17d..b5a8771d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,12 @@ "node": ">=0.10.0" } }, + "node_modules/@adobe/css-tools": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.1.tgz", + "integrity": "sha512-12WGKBQzjUAI4ayyF4IAtfw2QR/IDoqk6jTddXDhtYTJF9ASmoE1zst7cVtP0aL/F1jUJL5r+JxKXKEgHNbEUQ==", + "dev": true + }, "node_modules/@ampproject/remapping": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", @@ -6778,18 +6784,18 @@ } }, "node_modules/@playwright/test": { - "version": "1.40.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.40.1.tgz", - "integrity": "sha512-EaaawMTOeEItCRvfmkI9v6rBkF1svM8wjl/YPRrg2N2Wmp+4qJYkWtJsbew1szfKKDm6fPLy4YAanBhIlf9dWw==", + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.1.tgz", + "integrity": "sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==", "dev": true, "dependencies": { - "playwright": "1.40.1" + "playwright": "1.49.1" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { @@ -10866,6 +10872,112 @@ "node": ">=8" } }, + "node_modules/@testing-library/jest-dom": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.3.tgz", + "integrity": "sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==", + "dev": true, + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.21", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true + }, + "node_modules/@testing-library/jest-dom/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/user-event": { + "version": "14.5.2", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", + "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", + "dev": true, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -16430,6 +16542,12 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -30008,33 +30126,33 @@ } }, "node_modules/playwright": { - "version": "1.40.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.40.1.tgz", - "integrity": "sha512-2eHI7IioIpQ0bS1Ovg/HszsN/XKNwEG1kbzSDDmADpclKc7CyqkHw7Mg2JCz/bbCxg25QUPcjksoMW7JcIFQmw==", + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.1.tgz", + "integrity": "sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==", "dev": true, "dependencies": { - "playwright-core": "1.40.1" + "playwright-core": "1.49.1" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" }, "optionalDependencies": { "fsevents": "2.3.2" } }, "node_modules/playwright-core": { - "version": "1.40.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.40.1.tgz", - "integrity": "sha512-+hkOycxPiV534c4HhpfX6yrlawqVUzITRKwHAmYfmsVreltEl6fAZJ3DPfLMOODw0H3s1Itd6MDCWmP1fl/QvQ==", + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.1.tgz", + "integrity": "sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==", "dev": true, "bin": { "playwright-core": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/pluralize": { @@ -31027,6 +31145,65 @@ "typescript": ">= 4.3.x" } }, + "node_modules/react-docgen-typescript-plugin": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.8.tgz", + "integrity": "sha512-r+dUkpm/dmiVvvrfOTYbbg0g7bmaeXTodQFIru8ZzCx/HNUAUNSmh1C0seXzDSLqDSXm5EiOAiJZVs4gqAZqzA==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "find-cache-dir": "^3.3.1", + "flat-cache": "^3.0.4", + "micromatch": "^4.0.2", + "react-docgen-typescript": "^2.2.2", + "tslib": "^2.6.2" + }, + "peerDependencies": { + "typescript": ">= 4.x", + "webpack": ">= 4" + } + }, + "node_modules/react-docgen-typescript-plugin/node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/react-docgen-typescript-plugin/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-docgen-typescript-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/react-docgen/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -31047,16 +31224,6 @@ "react": "17.0.2" } }, - "node_modules/react-dom/node_modules/scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, "node_modules/react-element-to-jsx-string": { "version": "14.3.4", "resolved": "https://registry.npmjs.org/react-element-to-jsx-string/-/react-element-to-jsx-string-14.3.4.tgz", @@ -32632,6 +32799,16 @@ "node": ">=v12.22.7" } }, + "node_modules/scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, "node_modules/schema-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", @@ -38437,8 +38614,10 @@ "@storybook/addon-links": "^6.4.9", "@storybook/react": "^6.4.9", "@storybook/storybook-deployer": "^2.8.10", + "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^7.0.2", + "@testing-library/user-event": "^14.5.2", "@types/jest": "^27.4.0", "@types/react": "^17.0.39", "@types/react-dom": "^17.0.11", @@ -38455,8 +38634,9 @@ "husky": "^7.0.4", "jest": "^27.5.1", "jest-mock-extended": "^2.0.4", - "react": "^16.14.0", - "react-dom": "^16.14.0", + "react": "^17.0.2", + "react-docgen-typescript-plugin": "^1.0.8", + "react-dom": "^17.0.2", "react-element-to-jsx-string": "^14.3.4", "react-error-boundary": "^3.1.4", "react-is": "^17.0.2", @@ -38464,6 +38644,7 @@ "rollup": "^2.67.3", "rollup-plugin-cleanup": "^3.2.1", "rollup-plugin-terser": "^7.0.2", + "scheduler": "^0.20.2", "semver": "^7.3.5", "standard-version": "^9.3.2", "string-template": "^1.0.0", @@ -39298,35 +39479,6 @@ "sourcemap-codec": "^1.4.8" } }, - "packages/react-paypal-js/node_modules/react": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", - "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/react-paypal-js/node_modules/react-dom": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", - "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.19.1" - }, - "peerDependencies": { - "react": "^16.14.0" - } - }, "packages/react-paypal-js/node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -39364,16 +39516,6 @@ "rollup": "^2.0.0" } }, - "packages/react-paypal-js/node_modules/scheduler": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", - "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, "packages/react-paypal-js/node_modules/semver": { "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", @@ -39440,6 +39582,12 @@ "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "dev": true }, + "@adobe/css-tools": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.1.tgz", + "integrity": "sha512-12WGKBQzjUAI4ayyF4IAtfw2QR/IDoqk6jTddXDhtYTJF9ASmoE1zst7cVtP0aL/F1jUJL5r+JxKXKEgHNbEUQ==", + "dev": true + }, "@ampproject/remapping": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", @@ -44733,8 +44881,10 @@ "@storybook/addon-links": "^6.4.9", "@storybook/react": "^6.4.9", "@storybook/storybook-deployer": "^2.8.10", + "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^7.0.2", + "@testing-library/user-event": "^14.5.2", "@types/jest": "^27.4.0", "@types/react": "^17.0.39", "@types/react-dom": "^17.0.11", @@ -44751,8 +44901,9 @@ "husky": "^7.0.4", "jest": "^27.5.1", "jest-mock-extended": "^2.0.4", - "react": "^16.14.0", - "react-dom": "^16.14.0", + "react": "^17.0.2", + "react-docgen-typescript-plugin": "^1.0.8", + "react-dom": "^17.0.2", "react-element-to-jsx-string": "^14.3.4", "react-error-boundary": "^3.1.4", "react-is": "^17.0.2", @@ -44760,6 +44911,7 @@ "rollup": "^2.67.3", "rollup-plugin-cleanup": "^3.2.1", "rollup-plugin-terser": "^7.0.2", + "scheduler": "^0.20.2", "semver": "^7.3.5", "standard-version": "^9.3.2", "string-template": "^1.0.0", @@ -45320,29 +45472,6 @@ "sourcemap-codec": "^1.4.8" } }, - "react": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", - "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" - } - }, - "react-dom": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", - "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.19.1" - } - }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -45370,16 +45499,6 @@ "terser": "^5.0.0" } }, - "scheduler": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", - "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, "semver": { "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", @@ -45430,12 +45549,12 @@ } }, "@playwright/test": { - "version": "1.40.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.40.1.tgz", - "integrity": "sha512-EaaawMTOeEItCRvfmkI9v6rBkF1svM8wjl/YPRrg2N2Wmp+4qJYkWtJsbew1szfKKDm6fPLy4YAanBhIlf9dWw==", + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.1.tgz", + "integrity": "sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==", "dev": true, "requires": { - "playwright": "1.40.1" + "playwright": "1.49.1" } }, "@pmmmwh/react-refresh-webpack-plugin": { @@ -48435,6 +48554,85 @@ } } }, + "@testing-library/jest-dom": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.3.tgz", + "integrity": "sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==", + "dev": true, + "requires": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.21", + "redent": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@testing-library/user-event": { + "version": "14.5.2", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", + "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", + "dev": true, + "requires": {} + }, "@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -52810,6 +53008,12 @@ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", "dev": true }, + "css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true + }, "cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -63242,19 +63446,19 @@ } }, "playwright": { - "version": "1.40.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.40.1.tgz", - "integrity": "sha512-2eHI7IioIpQ0bS1Ovg/HszsN/XKNwEG1kbzSDDmADpclKc7CyqkHw7Mg2JCz/bbCxg25QUPcjksoMW7JcIFQmw==", + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.1.tgz", + "integrity": "sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==", "dev": true, "requires": { "fsevents": "2.3.2", - "playwright-core": "1.40.1" + "playwright-core": "1.49.1" } }, "playwright-core": { - "version": "1.40.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.40.1.tgz", - "integrity": "sha512-+hkOycxPiV534c4HhpfX6yrlawqVUzITRKwHAmYfmsVreltEl6fAZJ3DPfLMOODw0H3s1Itd6MDCWmP1fl/QvQ==", + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.1.tgz", + "integrity": "sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==", "dev": true }, "pluralize": { @@ -64025,6 +64229,48 @@ "dev": true, "requires": {} }, + "react-docgen-typescript-plugin": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.8.tgz", + "integrity": "sha512-r+dUkpm/dmiVvvrfOTYbbg0g7bmaeXTodQFIru8ZzCx/HNUAUNSmh1C0seXzDSLqDSXm5EiOAiJZVs4gqAZqzA==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "find-cache-dir": "^3.3.1", + "flat-cache": "^3.0.4", + "micromatch": "^4.0.2", + "react-docgen-typescript": "^2.2.2", + "tslib": "^2.6.2" + }, + "dependencies": { + "find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + } + } + }, "react-dom": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", @@ -64034,18 +64280,6 @@ "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "scheduler": "^0.20.2" - }, - "dependencies": { - "scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - } } }, "react-element-to-jsx-string": { @@ -65278,6 +65512,16 @@ "xmlchars": "^2.2.0" } }, + "scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, "schema-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", diff --git a/packages/react-paypal-js/.storybook/main.js b/packages/react-paypal-js/.storybook/main.js index 6c7356ec..b598df77 100644 --- a/packages/react-paypal-js/.storybook/main.js +++ b/packages/react-paypal-js/.storybook/main.js @@ -16,7 +16,7 @@ module.exports = { typescript: { check: false, checkOptions: {}, - reactDocgen: "react-docgen-typescript", + reactDocgen: "react-docgen-typescript-plugin", reactDocgenTypescriptOptions: { // the Storybook docs need this to render the props table for compilerOptions: { diff --git a/packages/react-paypal-js/jest.setup.ts b/packages/react-paypal-js/jest.setup.ts new file mode 100644 index 00000000..d0de870d --- /dev/null +++ b/packages/react-paypal-js/jest.setup.ts @@ -0,0 +1 @@ +import "@testing-library/jest-dom"; diff --git a/packages/react-paypal-js/package.json b/packages/react-paypal-js/package.json index 840d8078..dd23d5bb 100644 --- a/packages/react-paypal-js/package.json +++ b/packages/react-paypal-js/package.json @@ -66,8 +66,10 @@ "@storybook/addon-links": "^6.4.9", "@storybook/react": "^6.4.9", "@storybook/storybook-deployer": "^2.8.10", + "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^7.0.2", + "@testing-library/user-event": "^14.5.2", "@types/jest": "^27.4.0", "@types/react": "^17.0.39", "@types/react-dom": "^17.0.11", @@ -84,8 +86,9 @@ "husky": "^7.0.4", "jest": "^27.5.1", "jest-mock-extended": "^2.0.4", - "react": "^16.14.0", - "react-dom": "^16.14.0", + "react": "^17.0.2", + "react-docgen-typescript-plugin": "^1.0.8", + "react-dom": "^17.0.2", "react-element-to-jsx-string": "^14.3.4", "react-error-boundary": "^3.1.4", "react-is": "^17.0.2", @@ -93,6 +96,7 @@ "rollup": "^2.67.3", "rollup-plugin-cleanup": "^3.2.1", "rollup-plugin-terser": "^7.0.2", + "scheduler": "^0.20.2", "semver": "^7.3.5", "standard-version": "^9.3.2", "string-template": "^1.0.0", @@ -105,6 +109,9 @@ "jest": { "transformIgnorePatterns": [ "/!node_modules\\/@paypal\\/sdk-constants/" + ], + "setupFilesAfterEnv": [ + "./jest.setup.ts" ] }, "bugs": { diff --git a/packages/react-paypal-js/rollup.config.js b/packages/react-paypal-js/rollup.config.js index 3969be36..9c220e6f 100644 --- a/packages/react-paypal-js/rollup.config.js +++ b/packages/react-paypal-js/rollup.config.js @@ -9,7 +9,8 @@ import pkg from "./package.json"; const pkgName = pkg.name.split("@paypal/")[1]; const banner = getBannerText(); const tsconfigOverride = { - exclude: ["node_modules", "**/*.test.ts"], + exclude: ["node_modules", "**/*.test.ts*"], + outDir: "./dist", target: "es5", }; @@ -19,6 +20,7 @@ export default [ input: "src/index.ts", plugins: [ typescript({ + tsconfig: "./tsconfig.lib.json", ...tsconfigOverride, }), nodeResolve(), @@ -56,7 +58,10 @@ export default [ { input: "src/index.ts", plugins: [ - typescript({ ...tsconfigOverride }), + typescript({ + tsconfig: "./tsconfig.lib.json", + ...tsconfigOverride, + }), nodeResolve(), cleanup({ comments: "none", diff --git a/packages/react-paypal-js/src/components/PayPalButtons.test.tsx b/packages/react-paypal-js/src/components/PayPalButtons.test.tsx index 89569775..66a03542 100644 --- a/packages/react-paypal-js/src/components/PayPalButtons.test.tsx +++ b/packages/react-paypal-js/src/components/PayPalButtons.test.tsx @@ -6,6 +6,7 @@ import { fireEvent, act, } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; import { ErrorBoundary } from "react-error-boundary"; import { mock } from "jest-mock-extended"; import { loadScript } from "@paypal/paypal-js"; @@ -450,17 +451,71 @@ describe("", () => { test("should accept button message amount as a string", async () => { render( - - + + , ); await waitFor(() => expect(window.paypal?.Buttons).toHaveBeenCalledWith({ message: { amount: "100" }, onInit: expect.any(Function), - }) + }), ); }); + + test("should not create a stale closure when passing callbacks", async () => { + userEvent.setup(); + + // @ts-expect-error mocking partial ButtonComponent + window.paypal!.Buttons = ({ onClick }: { onClick: () => void }) => ({ + isEligible: () => true, + close: async () => undefined, + render: async (ref: HTMLDivElement) => { + const el = document.createElement("button"); + el.id = "mock-button"; + el.textContent = "Pay"; + el.addEventListener("click", onClick); + ref.appendChild(el); + }, + }); + const onClickFn = jest.fn(); + + const Wrapper = () => { + const [count, setCount] = useState(0); + + function onClick() { + onClickFn(count); + } + + return ( +
+ + + + +
+ ); + }; + + render(); + + const countButton = screen.getByTestId("count-button"); + const payButton = await screen.findByText("Pay"); + expect(screen.getByText("Count: 0")).toBeInTheDocument(); + + await userEvent.click(countButton); + expect(await screen.findByText("Count: 1")).toBeInTheDocument(); + await userEvent.click(payButton); + expect(onClickFn).toHaveBeenCalledWith(1); + + await userEvent.click(countButton); + expect(await screen.findByText("Count: 2")).toBeInTheDocument(); + await userEvent.click(payButton); + expect(onClickFn).toHaveBeenCalledWith(2); + }); }); diff --git a/packages/react-paypal-js/src/components/PayPalButtons.tsx b/packages/react-paypal-js/src/components/PayPalButtons.tsx index 2186cfec..8287a975 100644 --- a/packages/react-paypal-js/src/components/PayPalButtons.tsx +++ b/packages/react-paypal-js/src/components/PayPalButtons.tsx @@ -7,6 +7,7 @@ import { SDK_SETTINGS } from "../constants"; import type { FunctionComponent } from "react"; import type { PayPalButtonsComponent, OnInitActions } from "@paypal/paypal-js"; import type { PayPalButtonsComponentProps } from "../types"; +import { useProxyProps } from "../hooks/useProxyProps"; /** This `` component supports rendering [buttons](https://developer.paypal.com/docs/business/javascript-sdk/javascript-sdk-reference/#buttons) for PayPal, Venmo, and alternative payment methods. @@ -25,6 +26,7 @@ export const PayPalButtons: FunctionComponent = ({ }`.trim(); const buttonsContainerRef = useRef(null); const buttons = useRef(null); + const proxyProps = useProxyProps(buttonProps); const [{ isResolved, options }] = usePayPalScriptReducer(); const [initActions, setInitActions] = useState(null); @@ -86,7 +88,7 @@ export const PayPalButtons: FunctionComponent = ({ try { buttons.current = paypalWindowNamespace.Buttons({ - ...buttonProps, + ...proxyProps, onInit: decoratedOnInit, }); } catch (err) { diff --git a/packages/react-paypal-js/src/hooks/useProxyProps.test.ts b/packages/react-paypal-js/src/hooks/useProxyProps.test.ts new file mode 100644 index 00000000..4300994c --- /dev/null +++ b/packages/react-paypal-js/src/hooks/useProxyProps.test.ts @@ -0,0 +1,57 @@ +import { + CreateOrderActions, + CreateOrderData, + OnClickActions, +} from "@paypal/paypal-js"; +import { renderHook } from "@testing-library/react-hooks"; +import { useProxyProps } from "./useProxyProps"; + +describe("useProxyProps", () => { + test("should return an object of wrapped callbacks", () => { + const createOrder = jest.fn().mockReturnValue("createOrder"); + const onClick = jest.fn().mockReturnValue("onClick"); + + const props = { + createOrder, + onClick, + }; + + const { + result: { current }, + } = renderHook(() => useProxyProps(props)); + + expect(current).toHaveProperty("createOrder"); + expect(current).toHaveProperty("onClick"); + expect(current.createOrder).not.toBe(props.createOrder); + expect(current.onClick).not.toBe(props.onClick); + + expect( + current.createOrder!( + {} as CreateOrderData, + {} as CreateOrderActions, + ), + ).toBe("createOrder"); + expect(current.onClick!({}, {} as OnClickActions)).toBe("onClick"); + + expect(props.createOrder).toHaveBeenCalled(); + expect(props.onClick).toHaveBeenCalled(); + + // ensure no props mutation + expect(props.createOrder).toBe(createOrder); + expect(props.onClick).toBe(onClick); + }); + + test("should not wrap or mutate non-function props", () => { + const fundingSource = ["paypal"]; + const props = { + fundingSource, + }; + + const { + result: { current }, + } = renderHook(() => useProxyProps(props)); + + expect(current.fundingSource).toBe(props.fundingSource); + expect(props.fundingSource).toBe(fundingSource); + }); +}); diff --git a/packages/react-paypal-js/src/hooks/useProxyProps.ts b/packages/react-paypal-js/src/hooks/useProxyProps.ts new file mode 100644 index 00000000..70fdec31 --- /dev/null +++ b/packages/react-paypal-js/src/hooks/useProxyProps.ts @@ -0,0 +1,31 @@ +import { useRef } from "react"; + +export function useProxyProps>( + props: T, +): T { + const proxyRef = useRef( + new Proxy({} as T, { + get(target: T, prop: PropertyKey, receiver) { + /** + * + * If target[prop] is a function, return a function that accesses + * this function off the target object. We can mutate the target with + * new copies of this function without having to re-render the + * SDK components to pass new callbacks. + * + * */ + if (typeof target[prop] === "function") { + return (...args: unknown[]) => + // eslint-disable-next-line @typescript-eslint/ban-types + (target[prop] as Function)(...args); + } + + return Reflect.get(target, prop, receiver); + }, + }), + ); + + proxyRef.current = Object.assign(proxyRef.current, props); + + return proxyRef.current; +} diff --git a/packages/react-paypal-js/src/stories/payPalButtons/PayPalButtons.stories.tsx b/packages/react-paypal-js/src/stories/payPalButtons/PayPalButtons.stories.tsx index b478039f..7e73c00a 100644 --- a/packages/react-paypal-js/src/stories/payPalButtons/PayPalButtons.stories.tsx +++ b/packages/react-paypal-js/src/stories/payPalButtons/PayPalButtons.stories.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import { action } from "@storybook/addon-actions"; import { usePayPalScriptReducer, DISPATCH_ACTION } from "../../index"; @@ -256,3 +256,58 @@ export const Donate: FC> = ({ fundingSource: { control: false }, showSpinner: { table: { disable: true } }, }; + +export const WithDynamicOrderState: FC = ({ + style, + message, + fundingSource, + disabled, + showSpinner, +}) => { + const [count, setCount] = useState(0); + const [{ options }, dispatch] = usePayPalScriptReducer(); + useEffect(() => { + dispatch({ + type: DISPATCH_ACTION.RESET_OPTIONS, + value: { + ...options, + "data-order-id": Date.now().toString(), + }, + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [showSpinner]); + + return ( + <> + {showSpinner && } + + + createOrder([{ sku: "1blwyeo8", quantity: count }]).then( + (orderData) => { + if (orderData.id) { + action(ORDER_ID)(orderData.id); + return orderData.id; + } else { + throw new Error("failed to create Order Id"); + } + }, + ) + } + onApprove={(data) => + onApprove(data).then((orderData) => + action(APPROVE)(orderData), + ) + } + {...defaultProps} + > + + + + ); +}; diff --git a/packages/react-paypal-js/tsconfig.json b/packages/react-paypal-js/tsconfig.json index b5222a38..4e458c8d 100644 --- a/packages/react-paypal-js/tsconfig.json +++ b/packages/react-paypal-js/tsconfig.json @@ -9,11 +9,10 @@ "moduleResolution": "node", "target": "esnext", "strict": true, - "skipLibCheck": true, - - // these are overridden by the Rollup plugin - "outDir": "./dist", - "rootDir": "./src" + "skipLibCheck": true }, - "include": ["src"] + "references": [ + { "path": "./tsconfig.lib.json" }, + { "path": "./tsconfig.test.json" } + ] } diff --git a/packages/react-paypal-js/tsconfig.lib.json b/packages/react-paypal-js/tsconfig.lib.json new file mode 100644 index 00000000..bc3f3a49 --- /dev/null +++ b/packages/react-paypal-js/tsconfig.lib.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + // these are overridden by the Rollup plugin + "outDir": "./dist", + "rootDir": "./src", + "include": ["src/**/*.ts", "src/**/*.tsx"], + "exclude": ["src/**/*.test.ts", "src/**/*.test.tsx"] +} diff --git a/packages/react-paypal-js/tsconfig.test.json b/packages/react-paypal-js/tsconfig.test.json new file mode 100644 index 00000000..0de73f98 --- /dev/null +++ b/packages/react-paypal-js/tsconfig.test.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.test.ts", "src/**/*.test.tsx", "jest.setup.ts"] +} From ae050052f6276e82f64d51b9a9e0c77ac25f7afb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 16 Jan 2025 09:42:24 -0600 Subject: [PATCH 2/4] Version Packages (#606) Co-authored-by: github-actions[bot] --- .changeset/polite-snakes-enjoy.md | 5 ----- package-lock.json | 2 +- packages/react-paypal-js/CHANGELOG.md | 6 ++++++ packages/react-paypal-js/package.json | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) delete mode 100644 .changeset/polite-snakes-enjoy.md diff --git a/.changeset/polite-snakes-enjoy.md b/.changeset/polite-snakes-enjoy.md deleted file mode 100644 index 657ae9c0..00000000 --- a/.changeset/polite-snakes-enjoy.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@paypal/react-paypal-js": minor ---- - -(fix) proxy props to prevent stale closure diff --git a/package-lock.json b/package-lock.json index b5a8771d..2bd25534 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38590,7 +38590,7 @@ }, "packages/react-paypal-js": { "name": "@paypal/react-paypal-js", - "version": "8.7.0", + "version": "8.8.0", "license": "Apache-2.0", "dependencies": { "@paypal/paypal-js": "^8.1.2", diff --git a/packages/react-paypal-js/CHANGELOG.md b/packages/react-paypal-js/CHANGELOG.md index 450afeca..93e8b289 100644 --- a/packages/react-paypal-js/CHANGELOG.md +++ b/packages/react-paypal-js/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 8.8.0 + +### Minor Changes + +- 471280d: (fix) proxy props to prevent stale closure + ## 8.7.0 ### Minor Changes diff --git a/packages/react-paypal-js/package.json b/packages/react-paypal-js/package.json index dd23d5bb..efe77e4d 100644 --- a/packages/react-paypal-js/package.json +++ b/packages/react-paypal-js/package.json @@ -1,6 +1,6 @@ { "name": "@paypal/react-paypal-js", - "version": "8.7.0", + "version": "8.8.0", "description": "React components for the PayPal JS SDK", "keywords": [ "react", From 10775ad042401f631b36c11122e19c5b86e14acb Mon Sep 17 00:00:00 2001 From: Shane Brunson Date: Thu, 16 Jan 2025 11:25:10 -0600 Subject: [PATCH 3/4] fix release job, add react 19 as peer dependency (#608) * fix release job, add react 19 as peer dependency * upgrade artifact upload github action --- .changeset/grumpy-tigers-build.md | 5 +++++ .github/workflows/playwright.yml | 2 +- packages/react-paypal-js/package.json | 4 ++-- packages/react-paypal-js/tsconfig.declarations.json | 2 +- scripts/check-node-version.js | 2 +- 5 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 .changeset/grumpy-tigers-build.md diff --git a/.changeset/grumpy-tigers-build.md b/.changeset/grumpy-tigers-build.md new file mode 100644 index 00000000..d5203f00 --- /dev/null +++ b/.changeset/grumpy-tigers-build.md @@ -0,0 +1,5 @@ +--- +"@paypal/react-paypal-js": patch +--- + +minor fixes to release and adding react 19 as peer dependency diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 52d1a6c8..946bd9a1 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -39,7 +39,7 @@ jobs: - name: ▶️ Run Playwright tests run: npm run test:e2e - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: always() with: name: playwright-report diff --git a/packages/react-paypal-js/package.json b/packages/react-paypal-js/package.json index efe77e4d..90b91db0 100644 --- a/packages/react-paypal-js/package.json +++ b/packages/react-paypal-js/package.json @@ -103,8 +103,8 @@ "typescript": "^4.7.2" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17 || ^18 || ^19", + "react-dom": "^16.8.0 || ^17 || ^18 || ^19" }, "jest": { "transformIgnorePatterns": [ diff --git a/packages/react-paypal-js/tsconfig.declarations.json b/packages/react-paypal-js/tsconfig.declarations.json index 1136a11d..595610ca 100644 --- a/packages/react-paypal-js/tsconfig.declarations.json +++ b/packages/react-paypal-js/tsconfig.declarations.json @@ -1,5 +1,5 @@ { "extends": "./tsconfig.json", "include": ["src"], - "exclude": ["src/stories"] + "exclude": ["src/stories", "src/**/*.test.ts", "src/**/*.test.tsx"] } diff --git a/scripts/check-node-version.js b/scripts/check-node-version.js index 0cbe0d06..953b6071 100644 --- a/scripts/check-node-version.js +++ b/scripts/check-node-version.js @@ -3,7 +3,7 @@ const { join } = require("path"); const semver = require("semver"); const expectedNodeVersion = readFileSync( - join(__dirname, "../", ".nvmrc"), + join(__dirname, "../../", ".nvmrc"), "utf-8", ); const isValidNodeVersion = semver.satisfies( From cff6d0f685c1986951dd81b436db968f74b114c6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 16 Jan 2025 11:31:22 -0600 Subject: [PATCH 4/4] Version Packages (#609) Co-authored-by: github-actions[bot] --- .changeset/grumpy-tigers-build.md | 5 ----- package-lock.json | 6 +++--- packages/react-paypal-js/CHANGELOG.md | 6 ++++++ packages/react-paypal-js/package.json | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) delete mode 100644 .changeset/grumpy-tigers-build.md diff --git a/.changeset/grumpy-tigers-build.md b/.changeset/grumpy-tigers-build.md deleted file mode 100644 index d5203f00..00000000 --- a/.changeset/grumpy-tigers-build.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@paypal/react-paypal-js": patch ---- - -minor fixes to release and adding react 19 as peer dependency diff --git a/package-lock.json b/package-lock.json index 2bd25534..8fe53fd1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38590,7 +38590,7 @@ }, "packages/react-paypal-js": { "name": "@paypal/react-paypal-js", - "version": "8.8.0", + "version": "8.8.1", "license": "Apache-2.0", "dependencies": { "@paypal/paypal-js": "^8.1.2", @@ -38651,8 +38651,8 @@ "typescript": "^4.7.2" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17 || ^18 || ^19", + "react-dom": "^16.8.0 || ^17 || ^18 || ^19" } }, "packages/react-paypal-js/node_modules/@codesandbox/sandpack-react": { diff --git a/packages/react-paypal-js/CHANGELOG.md b/packages/react-paypal-js/CHANGELOG.md index 93e8b289..d58a9d0d 100644 --- a/packages/react-paypal-js/CHANGELOG.md +++ b/packages/react-paypal-js/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 8.8.1 + +### Patch Changes + +- 10775ad: minor fixes to release and adding react 19 as peer dependency + ## 8.8.0 ### Minor Changes diff --git a/packages/react-paypal-js/package.json b/packages/react-paypal-js/package.json index 90b91db0..a4c00d80 100644 --- a/packages/react-paypal-js/package.json +++ b/packages/react-paypal-js/package.json @@ -1,6 +1,6 @@ { "name": "@paypal/react-paypal-js", - "version": "8.8.0", + "version": "8.8.1", "description": "React components for the PayPal JS SDK", "keywords": [ "react",