diff --git a/.changeset/bright-bees-press.md b/.changeset/bright-bees-press.md deleted file mode 100644 index 4b860cc6c..000000000 --- a/.changeset/bright-bees-press.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@headstartwp/core": patch -"@headstartwp/next": patch ---- - -Lower compilation target diff --git a/.changeset/bright-jokes-learn.md b/.changeset/bright-jokes-learn.md deleted file mode 100644 index 176119258..000000000 --- a/.changeset/bright-jokes-learn.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@headstartwp/core": patch ---- - -Fix theme.json handling in `useBlockColors` and `useBlockTypography`. - -Thanks @riccardodicurti @dhamibirendra for [the bug report](https://github.com/10up/headstartwp/issues/541). diff --git a/.changeset/curly-apricots-stare.md b/.changeset/curly-apricots-stare.md deleted file mode 100644 index 1c9c622b5..000000000 --- a/.changeset/curly-apricots-stare.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@headstartwp/next": patch ---- - -Fix: only convertUrls if url starts with sourceUrl diff --git a/.changeset/gentle-clouds-taste.md b/.changeset/gentle-clouds-taste.md deleted file mode 100644 index c15a0a43d..000000000 --- a/.changeset/gentle-clouds-taste.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@headstartwp/next": patch ---- - -Fix typo in files to be published to npm diff --git a/.changeset/good-papayas-laugh.md b/.changeset/good-papayas-laugh.md deleted file mode 100644 index 807155d3b..000000000 --- a/.changeset/good-papayas-laugh.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@headstartwp/core": patch ---- - -Fixes useSearch error when Yoast SEO plugin is deactivated. diff --git a/.changeset/hot-papayas-relate.md b/.changeset/hot-papayas-relate.md deleted file mode 100644 index 4483c7a09..000000000 --- a/.changeset/hot-papayas-relate.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@headstartwp/core": minor -"@headstartwp/next": minor ---- - -Introducing `usePostOrPosts`. diff --git a/.changeset/lovely-chicken-sparkle.md b/.changeset/lovely-chicken-sparkle.md deleted file mode 100644 index be5c587f1..000000000 --- a/.changeset/lovely-chicken-sparkle.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"@headstartwp/next": minor -"@headstartwp/headstartwp": patch -"@headstartwp/core": patch ---- - -Improves the Next.js preview cookie handling and fixes a bug where the locale was not properly being passed from WP when previewing. - -First of all, it sets the preview cookie to expire within 5 minutes which aligns with the JWT token expiration. - -Secondly, it will narrow the cookie to the post path being previewed so that `context.preview` is not true for other paths and thus avoiding bypassing getStaticProps until the cookies are cleared (either expires or the browser closes). diff --git a/.changeset/mighty-stingrays-pay.md b/.changeset/mighty-stingrays-pay.md deleted file mode 100644 index f1b222387..000000000 --- a/.changeset/mighty-stingrays-pay.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@headstartwp/core": minor ---- - -Introduces `SafeHtml` and `HtmlDecoder` components. diff --git a/.changeset/popular-turkeys-sleep.md b/.changeset/popular-turkeys-sleep.md deleted file mode 100644 index 41538dba9..000000000 --- a/.changeset/popular-turkeys-sleep.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@headstartwp/core": minor ---- - -Introducing the `useSeo` hook. diff --git a/.changeset/pre.json b/.changeset/pre.json deleted file mode 100644 index 8772f19c7..000000000 --- a/.changeset/pre.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "mode": "pre", - "tag": "next", - "initialVersions": { - "@headstartwp/core": "1.0.6", - "@10up/react-hooks": "1.2.3", - "@headstartwp/next": "1.0.6", - "@10up/next-redis-cache-provider": "0.1.5", - "@10up/headless-docs": "1.0.0", - "@10up/wp-multisite-i18n-nextjs": "0.2.0", - "@10up/wp-multisite-nextjs": "0.2.0", - "@10up/wp-nextjs": "0.2.0", - "@10up/wp-nextjs-ts": "0.2.1-next.2", - "@headstartwp/headstartwp": "1.0.8" - }, - "changesets": [ - "bright-bees-press", - "bright-jokes-learn", - "curly-apricots-stare", - "gentle-clouds-taste", - "good-papayas-laugh", - "hot-papayas-relate", - "lovely-chicken-sparkle", - "mighty-stingrays-pay", - "popular-turkeys-sleep", - "proud-dryers-repeat", - "silent-kiwis-compare", - "tame-squids-fail", - "two-cats-vanish" - ] -} diff --git a/.changeset/proud-dryers-repeat.md b/.changeset/proud-dryers-repeat.md deleted file mode 100644 index 26a01a43d..000000000 --- a/.changeset/proud-dryers-repeat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@headstartwp/core": patch ---- - -Fix theme.json handling for block settings diff --git a/.changeset/silent-kiwis-compare.md b/.changeset/silent-kiwis-compare.md deleted file mode 100644 index 802583fb2..000000000 --- a/.changeset/silent-kiwis-compare.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@headstartwp/core": patch -"@headstartwp/next": patch ---- - -Further Optimize next.js props by removing yoast seo bloat. diff --git a/.changeset/tame-squids-fail.md b/.changeset/tame-squids-fail.md deleted file mode 100644 index afc38e0db..000000000 --- a/.changeset/tame-squids-fail.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@headstartwp/next": patch ---- - -Fix an annoying bug that would require deleting the .next/cache folder after changing headless.config.js or .env files. Now you only need to restart the next.js server after changing those files. diff --git a/.changeset/two-cats-vanish.md b/.changeset/two-cats-vanish.md deleted file mode 100644 index b63ce069a..000000000 --- a/.changeset/two-cats-vanish.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@headstartwp/core": minor ---- - -Introduces the `decodeHtmlSpecialChars` function. diff --git a/.github/workflows/phpcs.yml b/.github/workflows/phpcs.yml index 399185b12..a71c450e8 100644 --- a/.github/workflows/phpcs.yml +++ b/.github/workflows/phpcs.yml @@ -12,7 +12,7 @@ jobs: - name: Set PHP version uses: shivammathur/setup-php@v2 with: - php-version: '7.4' + php-version: '8.2' - name: composer install run: cd ./wp/headless-wp && composer install --ignore-platform-reqs - name: Check PHPCS standard diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 6adc964cd..0fbcfc9dc 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -6,13 +6,16 @@ jobs: phpunit: name: phpunit runs-on: ubuntu-latest + strategy: + matrix: + php-version: ['7.4', '8.0', '8.2'] steps: - name: Checkout uses: actions/checkout@v3 - name: Set PHP version uses: shivammathur/setup-php@v2 with: - php-version: "8.0" + php-version: ${{ matrix.php-version }} - name: npm install run: npm install - name: composer install diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index daa3efc1e..b517dc359 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: - node-version: [16.x] + node-version: [16.x, 18.x, 20.x] steps: - name: Checkout diff --git a/.nvmrc b/.nvmrc index 19c7bdba7..2edeafb09 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16 \ No newline at end of file +20 \ No newline at end of file diff --git a/docs/documentation/01-Getting Started/headless-config.md b/docs/documentation/01-Getting Started/headless-config.md index 14bb9127c..a24a34e9b 100644 --- a/docs/documentation/01-Getting Started/headless-config.md +++ b/docs/documentation/01-Getting Started/headless-config.md @@ -99,7 +99,7 @@ After adding a custom taxonomy to the config, you will be able to filter posts b ```js usePost({ postType: ['book'], genre: 'action' }); -usePosts({ postType:'book', genre: 'action' perPage: 10 }); +usePosts({ postType:'book', genre: 'action', perPage: 10 }); useTerms({ taxonomy: 'genre' }); ``` diff --git a/docs/documentation/02 - Data Fetching/useSeo.md b/docs/documentation/02 - Data Fetching/useSeo.md index 6cffc5658..4954439ab 100644 --- a/docs/documentation/02 - Data Fetching/useSeo.md +++ b/docs/documentation/02 - Data Fetching/useSeo.md @@ -21,4 +21,4 @@ const yoast_json = useSeo('json'); const yoast_head = useSeo('html'); ``` -If there's no seo information for the current route, this hook will return `null`. \ No newline at end of file +If there's no seo information for the current route, this hook will return `null` therefore we recommend checking for null before using the return value. \ No newline at end of file diff --git a/docs/documentation/06-WordPress Integration/basic-auth.md b/docs/documentation/06-WordPress Integration/basic-auth.md new file mode 100644 index 000000000..cc9f6d63e --- /dev/null +++ b/docs/documentation/06-WordPress Integration/basic-auth.md @@ -0,0 +1,19 @@ +--- +slug: /wordpress-integration/basic-auth +--- + +# Basic Auth + +If WordPress is protected by Basic Auth (which is common during development) you can tell HeadstartWP the basic auth creds so that all +REST API requests include them. To do so, simply add the following env variables: + +``` +WP_BASIC_AUTH_USERNAME=username +WP_BASIC_AUTH_PASSWORD=password +``` + +:::caution +The above env variables will only be accessible server-side and therefore any client-side requests made directly to WordPress will fail. This happens because Next.js only includes env variables prefixed with `NEXT_PUBLIC_` in the browser bundle. + +If you want your client-side requests to work, prefix the above variables with `NEXT_PUBLIC_`. But note that the basic auth creds will be leaked to the public. +:::caution diff --git a/docs/package-lock.json b/docs/package-lock.json index 41d9d56de..404455d76 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -181,16 +181,81 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/compat-data": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", @@ -237,12 +302,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", - "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dependencies": { - "@babel/types": "^7.20.5", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "engines": { @@ -370,9 +436,9 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "engines": { "node": ">=6.9.0" } @@ -389,23 +455,23 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dependencies": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -525,28 +591,28 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "engines": { "node": ">=6.9.0" } @@ -587,12 +653,12 @@ } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -664,9 +730,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", - "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "bin": { "parser": "bin/babel-parser.js" }, @@ -1905,31 +1971,31 @@ } }, "node_modules/@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", - "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.5", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.5", - "@babel/types": "^7.20.5", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1938,12 +2004,12 @@ } }, "node_modules/@babel/types": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", - "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -8349,9 +8415,15 @@ } }, "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -8905,9 +8977,9 @@ } }, "node_modules/postcss": { - "version": "8.4.20", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", - "integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "funding": [ { "type": "opencollective", @@ -8916,10 +8988,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -13104,11 +13180,63 @@ } }, "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "requires": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } } }, "@babel/compat-data": { @@ -13146,12 +13274,13 @@ } }, "@babel/generator": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", - "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "requires": { - "@babel/types": "^7.20.5", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "dependencies": { @@ -13246,9 +13375,9 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==" + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==" }, "@babel/helper-explode-assignable-expression": { "version": "7.18.6", @@ -13259,20 +13388,20 @@ } }, "@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "requires": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" } }, "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-member-expression-to-functions": { @@ -13359,22 +13488,22 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==" + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==" }, "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==" }, "@babel/helper-validator-option": { "version": "7.18.6", @@ -13403,12 +13532,12 @@ } }, "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "dependencies": { @@ -13464,9 +13593,9 @@ } }, "@babel/parser": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", - "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==" + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==" }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.18.6", @@ -14265,39 +14394,39 @@ } }, "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" } }, "@babel/traverse": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", - "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.5", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.5", - "@babel/types": "^7.20.5", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "requires": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", - "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "requires": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" } }, @@ -18955,9 +19084,9 @@ } }, "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==" }, "negotiator": { "version": "0.6.3", @@ -19350,11 +19479,11 @@ } }, "postcss": { - "version": "8.4.20", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", - "integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "requires": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } diff --git a/docs/static/img/documentation/getting-started/plugin-settings.png b/docs/static/img/documentation/getting-started/plugin-settings.png index 107eb3c87..6ef122389 100644 Binary files a/docs/static/img/documentation/getting-started/plugin-settings.png and b/docs/static/img/documentation/getting-started/plugin-settings.png differ diff --git a/package-lock.json b/package-lock.json index 300851db5..2b1d96eee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,8 +31,16 @@ "turbo": "^1.9.3" }, "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" + "node": ">=18.0.0", + "npm": ">=9.0.0" + }, + "optionalDependencies": { + "turbo-darwin-64": "^1.9.3", + "turbo-darwin-arm64": "^1.9.3", + "turbo-linux-64": "^1.9.3", + "turbo-linux-arm64": "^1.9.3", + "turbo-windows-64": "^1.9.3", + "turbo-windows-arm64": "^1.9.3" } }, "node_modules/@10up/babel-preset-default": { @@ -129,10 +137,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.21.4", - "license": "MIT", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" @@ -192,10 +202,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.21.5", - "license": "MIT", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dependencies": { - "@babel/types": "^7.21.5", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -293,28 +304,31 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.21.5", - "license": "MIT", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.21.0", - "license": "MIT", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dependencies": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "license": "MIT", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -426,25 +440,28 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "license": "MIT", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.21.5", - "license": "MIT", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "license": "MIT", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "engines": { "node": ">=6.9.0" } @@ -482,11 +499,12 @@ } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "license": "MIT", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -494,8 +512,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.21.8", - "license": "MIT", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "bin": { "parser": "bin/babel-parser.js" }, @@ -1702,29 +1721,31 @@ } }, "node_modules/@babel/template": { - "version": "7.20.7", - "license": "MIT", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.21.5", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.5", - "@babel/helper-environment-visitor": "^7.21.5", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.5", - "@babel/types": "^7.21.5", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1733,11 +1754,12 @@ } }, "node_modules/@babel/types": { - "version": "7.21.5", - "license": "MIT", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dependencies": { - "@babel/helper-string-parser": "^7.21.5", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1770,9 +1792,10 @@ } }, "node_modules/@changesets/apply-release-plan/node_modules/semver": { - "version": "5.7.1", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver" } @@ -1791,9 +1814,10 @@ } }, "node_modules/@changesets/assemble-release-plan/node_modules/semver": { - "version": "5.7.1", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver" } @@ -1850,9 +1874,10 @@ } }, "node_modules/@changesets/cli/node_modules/semver": { - "version": "5.7.1", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver" } @@ -1892,9 +1917,10 @@ } }, "node_modules/@changesets/get-dependents-graph/node_modules/semver": { - "version": "5.7.1", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver" } @@ -3355,6 +3381,7 @@ }, "node_modules/@jridgewell/source-map": { "version": "0.3.3", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -4237,6 +4264,66 @@ "version": "13.4.4", "license": "MIT" }, + "node_modules/@next/swc-darwin-arm64": { + "version": "13.4.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.4.tgz", + "integrity": "sha512-xfjgXvp4KalNUKZMHmsFxr1Ug+aGmmO6NWP0uoh4G3WFqP/mJ1xxfww0gMOeMeSq/Jyr5k7DvoZ2Pv+XOITTtw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "13.4.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.4.tgz", + "integrity": "sha512-ZY9Ti1hkIwJsxGus3nlubIkvYyB0gNOYxKrfsOrLEqD0I2iCX8D7w8v6QQZ2H+dDl6UT29oeEUdDUNGk4UEpfg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "13.4.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.4.tgz", + "integrity": "sha512-+KZnDeMShYkpkqAvGCEDeqYTRADJXc6SY1jWXz+Uo6qWQO/Jd9CoyhTJwRSxvQA16MoYzvILkGaDqirkRNctyA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "13.4.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.4.tgz", + "integrity": "sha512-evC1twrny2XDT4uOftoubZvW3EG0zs0ZxMwEtu/dDGVRO5n5pT48S8qqEIBGBUZYu/Xx4zzpOkIxx1vpWdE+9A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@next/swc-linux-x64-gnu": { "version": "13.4.4", "cpu": [ @@ -4265,6 +4352,51 @@ "node": ">= 10" } }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "13.4.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.4.tgz", + "integrity": "sha512-FP8AadgSq4+HPtim7WBkCMGbhr5vh9FePXiWx9+YOdjwdQocwoCK5ZVC3OW8oh3TWth6iJ0AXJ/yQ1q1cwSZ3A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "13.4.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.4.tgz", + "integrity": "sha512-3WekVmtuA2MCdcAOrgrI+PuFiFURtSyyrN1I3UPtS0ckR2HtLqyqmS334Eulf15g1/bdwMteePdK363X/Y9JMg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "13.4.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.4.tgz", + "integrity": "sha512-AHRITu/CrlQ+qzoqQtEMfaTu7GHaQ6bziQln/pVWpOYC1wU+Mq6VQQFlsDtMCnDztPZtppAXdvvbNS7pcfRzlw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "dev": true, @@ -4731,6 +4863,7 @@ }, "node_modules/@types/eslint": { "version": "8.37.0", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -4740,6 +4873,7 @@ }, "node_modules/@types/eslint-scope": { "version": "3.7.4", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -4749,6 +4883,7 @@ }, "node_modules/@types/estree": { "version": "1.0.1", + "dev": true, "license": "MIT", "peer": true }, @@ -4894,6 +5029,7 @@ }, "node_modules/@types/node": { "version": "12.20.55", + "dev": true, "license": "MIT" }, "node_modules/@types/node-fetch": { @@ -5053,9 +5189,10 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.5.0", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -5189,9 +5326,10 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.5.0", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -5249,9 +5387,10 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.5.0", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -5296,6 +5435,7 @@ }, "node_modules/@webassemblyjs/ast": { "version": "1.11.5", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -5305,16 +5445,19 @@ }, "node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.11.5", + "dev": true, "license": "MIT", "peer": true }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.5", + "dev": true, "license": "MIT", "peer": true }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.11.5", + "dev": true, "license": "MIT", "peer": true }, @@ -5381,6 +5524,7 @@ }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.5", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -5391,11 +5535,13 @@ }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.5", + "dev": true, "license": "MIT", "peer": true }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.11.5", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -5407,6 +5553,7 @@ }, "node_modules/@webassemblyjs/ieee754": { "version": "1.11.5", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -5415,6 +5562,7 @@ }, "node_modules/@webassemblyjs/leb128": { "version": "1.11.5", + "dev": true, "license": "Apache-2.0", "peer": true, "dependencies": { @@ -5423,11 +5571,13 @@ }, "node_modules/@webassemblyjs/utf8": { "version": "1.11.5", + "dev": true, "license": "MIT", "peer": true }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.11.5", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -5443,6 +5593,7 @@ }, "node_modules/@webassemblyjs/wasm-gen": { "version": "1.11.5", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -5455,6 +5606,7 @@ }, "node_modules/@webassemblyjs/wasm-opt": { "version": "1.11.5", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -5466,6 +5618,7 @@ }, "node_modules/@webassemblyjs/wasm-parser": { "version": "1.11.5", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -5517,6 +5670,7 @@ }, "node_modules/@webassemblyjs/wast-printer": { "version": "1.11.5", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -5780,6 +5934,7 @@ }, "node_modules/acorn": { "version": "8.8.2", + "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -5799,6 +5954,7 @@ }, "node_modules/acorn-import-assertions": { "version": "1.8.0", + "dev": true, "license": "MIT", "peer": true, "peerDependencies": { @@ -7720,9 +7876,10 @@ } }, "node_modules/conventional-commits-parser/node_modules/semver": { - "version": "7.5.0", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -8794,6 +8951,7 @@ }, "node_modules/es-module-lexer": { "version": "1.2.1", + "dev": true, "license": "MIT", "peer": true }, @@ -9221,9 +9379,10 @@ } }, "node_modules/eslint-plugin-jsdoc/node_modules/semver": { - "version": "7.5.1", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, - "license": "ISC", "peer": true, "dependencies": { "lru-cache": "^6.0.0" @@ -9364,6 +9523,7 @@ }, "node_modules/eslint-scope": { "version": "5.1.1", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", @@ -9375,6 +9535,7 @@ }, "node_modules/eslint-scope/node_modules/estraverse": { "version": "4.3.0", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -10286,8 +10447,9 @@ } }, "node_modules/find-cache-dir/node_modules/semver": { - "version": "5.7.1", - "license": "ISC", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "peer": true, "bin": { "semver": "bin/semver" @@ -10760,9 +10922,10 @@ } }, "node_modules/git-raw-commits/node_modules/semver": { - "version": "7.5.0", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -10828,6 +10991,7 @@ }, "node_modules/glob-to-regexp": { "version": "0.4.1", + "dev": true, "license": "BSD-2-Clause", "peer": true }, @@ -13780,9 +13944,10 @@ "license": "MIT" }, "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.5.0", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -14522,6 +14687,7 @@ }, "node_modules/loader-runner": { "version": "4.3.0", + "dev": true, "license": "MIT", "peer": true, "engines": { @@ -14535,19 +14701,6 @@ "node": ">= 12.13.0" } }, - "node_modules/loader-utils-webpack-v4": { - "name": "loader-utils", - "version": "2.0.4", - "license": "MIT", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, "node_modules/locate-path": { "version": "6.0.0", "license": "MIT", @@ -14972,6 +15125,7 @@ }, "node_modules/merge-stream": { "version": "2.0.0", + "dev": true, "license": "MIT" }, "node_modules/merge2": { @@ -15201,17 +15355,6 @@ "node": ">=10" } }, - "node_modules/modify-source-webpack-plugin": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "loader-utils-webpack-v4": "npm:loader-utils@^2.0.4", - "schema-utils": "^4.0.0" - }, - "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - } - }, "node_modules/move-concurrently": { "version": "1.0.1", "license": "ISC", @@ -15744,9 +15887,10 @@ } }, "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver" } @@ -17872,8 +18016,9 @@ "license": "MIT" }, "node_modules/semver": { - "version": "6.3.0", - "license": "ISC", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "bin": { "semver": "bin/semver.js" } @@ -17932,6 +18077,7 @@ }, "node_modules/serialize-javascript": { "version": "6.0.1", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" @@ -19255,6 +19401,7 @@ }, "node_modules/terser": { "version": "5.17.1", + "dev": true, "license": "BSD-2-Clause", "peer": true, "dependencies": { @@ -19272,6 +19419,7 @@ }, "node_modules/terser-webpack-plugin": { "version": "5.3.7", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -19305,6 +19453,7 @@ }, "node_modules/terser-webpack-plugin/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "peer": true, "engines": { @@ -19313,6 +19462,7 @@ }, "node_modules/terser-webpack-plugin/node_modules/jest-worker": { "version": "27.5.1", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -19326,6 +19476,7 @@ }, "node_modules/terser-webpack-plugin/node_modules/schema-utils": { "version": "3.1.2", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -19343,6 +19494,7 @@ }, "node_modules/terser-webpack-plugin/node_modules/supports-color": { "version": "8.1.1", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -19357,11 +19509,13 @@ }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", + "dev": true, "license": "MIT", "peer": true }, "node_modules/terser/node_modules/source-map-support": { "version": "0.5.21", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -19519,9 +19673,10 @@ } }, "node_modules/tough-cookie": { - "version": "4.1.2", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -19631,9 +19786,10 @@ } }, "node_modules/ts-jest/node_modules/semver": { - "version": "7.5.0", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -19858,18 +20014,78 @@ "turbo-windows-arm64": "1.9.3" } }, + "node_modules/turbo-darwin-64": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/turbo-darwin-64/-/turbo-darwin-64-1.9.3.tgz", + "integrity": "sha512-0dFc2cWXl82kRE4Z+QqPHhbEFEpUZho1msHXHWbz5+PqLxn8FY0lEVOHkq5tgKNNEd5KnGyj33gC/bHhpZOk5g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/turbo-darwin-arm64": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-1.9.3.tgz", + "integrity": "sha512-1cYbjqLBA2zYE1nbf/qVnEkrHa4PkJJbLo7hnuMuGM0bPzh4+AnTNe98gELhqI1mkTWBu/XAEeF5u6dgz0jLNA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, "node_modules/turbo-linux-64": { "version": "1.9.3", + "resolved": "https://registry.npmjs.org/turbo-linux-64/-/turbo-linux-64-1.9.3.tgz", + "integrity": "sha512-UuBPFefawEwpuxh5pM9Jqq3q4C8M0vYxVYlB3qea/nHQ80pxYq7ZcaLGEpb10SGnr3oMUUs1zZvkXWDNKCJb8Q==", "cpu": [ "x64" ], - "dev": true, - "license": "MPL-2.0", "optional": true, "os": [ "linux" ] }, + "node_modules/turbo-linux-arm64": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/turbo-linux-arm64/-/turbo-linux-arm64-1.9.3.tgz", + "integrity": "sha512-vUrNGa3hyDtRh9W0MkO+l1dzP8Co2gKnOVmlJQW0hdpOlWlIh22nHNGGlICg+xFa2f9j4PbQlWTsc22c019s8Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/turbo-windows-64": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/turbo-windows-64/-/turbo-windows-64-1.9.3.tgz", + "integrity": "sha512-0BZ7YaHs6r+K4ksqWus1GKK3W45DuDqlmfjm/yuUbTEVc8szmMCs12vugU2Zi5GdrdJSYfoKfEJ/PeegSLIQGQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/turbo-windows-arm64": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/turbo-windows-arm64/-/turbo-windows-arm64-1.9.3.tgz", + "integrity": "sha512-QJUYLSsxdXOsR1TquiOmLdAgtYcQ/RuSRpScGvnZb1hY0oLc7JWU0llkYB81wVtWs469y8H9O0cxbKwCZGR4RQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/type-check": { "version": "0.4.0", "dev": true, @@ -20310,6 +20526,7 @@ }, "node_modules/watchpack": { "version": "2.4.0", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -20614,6 +20831,7 @@ }, "node_modules/webpack": { "version": "5.81.0", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -20774,6 +20992,7 @@ }, "node_modules/webpack-sources": { "version": "3.2.3", + "dev": true, "license": "MIT", "peer": true, "engines": { @@ -20782,6 +21001,7 @@ }, "node_modules/webpack/node_modules/schema-utils": { "version": "3.1.2", + "dev": true, "license": "MIT", "peer": true, "dependencies": { @@ -21158,7 +21378,7 @@ }, "packages/core": { "name": "@headstartwp/core", - "version": "1.1.0-next.1", + "version": "1.1.2", "license": "MIT", "dependencies": { "@justinribeiro/lite-youtube": "^1.3.1", @@ -21549,13 +21769,12 @@ }, "packages/next": { "name": "@headstartwp/next", - "version": "1.1.0-next.1", + "version": "1.1.6", "license": "MIT", "dependencies": { - "@headstartwp/core": "^1.1.0-next.1", + "@headstartwp/core": "^1.1.2", "deepmerge": "^4.3.1", "loader-utils": "^3.2.0", - "modify-source-webpack-plugin": "^4.1.0", "schema-utils": "^4.0.0" }, "devDependencies": { @@ -21714,8 +21933,8 @@ "version": "0.2.0", "license": "GPL-2.0-or-later", "dependencies": { - "@headstartwp/core": "^1.1.0-next.1", - "@headstartwp/next": "^1.1.0-next.1", + "@headstartwp/core": "^1.1.2", + "@headstartwp/next": "^1.1.6", "@linaria/babel-preset": "^4.4.5", "@linaria/core": "^4.2.10", "@linaria/react": "^4.3.8", @@ -21734,8 +21953,8 @@ "eslint-plugin-import": "^2.26.0" }, "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" + "node": ">=18.0.0", + "npm": ">=9.0.0" } }, "projects/wp-multisite-nextjs": { @@ -21743,8 +21962,8 @@ "version": "0.2.0", "license": "GPL-2.0-or-later", "dependencies": { - "@headstartwp/core": "^1.1.0-next.1", - "@headstartwp/next": "^1.1.0-next.1", + "@headstartwp/core": "^1.1.2", + "@headstartwp/next": "^1.1.6", "@linaria/babel-preset": "^4.4.5", "@linaria/core": "^4.2.10", "@linaria/react": "^4.3.8", @@ -21763,8 +21982,8 @@ "eslint-plugin-import": "^2.26.0" }, "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" + "node": ">=18.0.0", + "npm": ">=9.0.0" } }, "projects/wp-nextjs": { @@ -21773,8 +21992,8 @@ "license": "GPL-2.0-or-later", "dependencies": { "@10up/next-redis-cache-provider": "^0.1.5", - "@headstartwp/core": "^1.1.0-next.1", - "@headstartwp/next": "^1.1.0-next.1", + "@headstartwp/core": "^1.1.2", + "@headstartwp/next": "^1.1.6", "@linaria/babel-preset": "^4.4.5", "@linaria/core": "^4.2.10", "@linaria/react": "^4.3.8", @@ -21793,8 +22012,8 @@ "eslint-plugin-import": "^2.26.0" }, "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" + "node": ">=18.0.0", + "npm": ">=9.0.0" } }, "projects/wp-nextjs-ts": { @@ -21802,8 +22021,8 @@ "version": "0.2.1-next.2", "license": "GPL-2.0-or-later", "dependencies": { - "@headstartwp/core": "^1.1.0-next.1", - "@headstartwp/next": "^1.1.0-next.1", + "@headstartwp/core": "^1.1.2", + "@headstartwp/next": "^1.1.6", "@linaria/babel-preset": "^4.4.5", "@linaria/core": "^4.2.10", "@linaria/react": "^4.3.8", @@ -21822,13 +22041,13 @@ "eslint-plugin-import": "^2.26.0" }, "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" + "node": ">=18.0.0", + "npm": ">=9.0.0" } }, "wp/headless-wp": { "name": "@headstartwp/headstartwp", - "version": "1.0.9-next.0", + "version": "1.0.10", "license": "GPL-2.0-or-later", "devDependencies": { "@wordpress/env": "^5.14.0" @@ -21836,111 +22055,6 @@ "engines": { "node": ">=16.0.0" } - }, - "node_modules/@next/swc-darwin-arm64": { - "version": "13.4.4", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.4.tgz", - "integrity": "sha512-xfjgXvp4KalNUKZMHmsFxr1Ug+aGmmO6NWP0uoh4G3WFqP/mJ1xxfww0gMOeMeSq/Jyr5k7DvoZ2Pv+XOITTtw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-darwin-x64": { - "version": "13.4.4", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.4.tgz", - "integrity": "sha512-ZY9Ti1hkIwJsxGus3nlubIkvYyB0gNOYxKrfsOrLEqD0I2iCX8D7w8v6QQZ2H+dDl6UT29oeEUdDUNGk4UEpfg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "13.4.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.4.tgz", - "integrity": "sha512-+KZnDeMShYkpkqAvGCEDeqYTRADJXc6SY1jWXz+Uo6qWQO/Jd9CoyhTJwRSxvQA16MoYzvILkGaDqirkRNctyA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "13.4.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.4.tgz", - "integrity": "sha512-evC1twrny2XDT4uOftoubZvW3EG0zs0ZxMwEtu/dDGVRO5n5pT48S8qqEIBGBUZYu/Xx4zzpOkIxx1vpWdE+9A==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "13.4.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.4.tgz", - "integrity": "sha512-FP8AadgSq4+HPtim7WBkCMGbhr5vh9FePXiWx9+YOdjwdQocwoCK5ZVC3OW8oh3TWth6iJ0AXJ/yQ1q1cwSZ3A==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "13.4.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.4.tgz", - "integrity": "sha512-3WekVmtuA2MCdcAOrgrI+PuFiFURtSyyrN1I3UPtS0ckR2HtLqyqmS334Eulf15g1/bdwMteePdK363X/Y9JMg==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "13.4.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.4.tgz", - "integrity": "sha512-AHRITu/CrlQ+qzoqQtEMfaTu7GHaQ6bziQln/pVWpOYC1wU+Mq6VQQFlsDtMCnDztPZtppAXdvvbNS7pcfRzlw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } } } } diff --git a/package.json b/package.json index 45fd59ff0..ad8cad075 100644 --- a/package.json +++ b/package.json @@ -56,10 +56,18 @@ }, "engineStrict": true, "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" + "node": ">=18.0.0", + "npm": ">=9.0.0" }, "dependencies": { "express": "^4.18.1" + }, + "optionalDependencies": { + "turbo-darwin-64": "^1.9.3", + "turbo-darwin-arm64": "^1.9.3", + "turbo-linux-64": "^1.9.3", + "turbo-linux-arm64": "^1.9.3", + "turbo-windows-64": "^1.9.3", + "turbo-windows-arm64": "^1.9.3" } } diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index f59f14e16..c771ee8ae 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,56 @@ # @headstartwp/core +## 1.1.2 + +### Patch Changes + +- 15189a03: Adding support for basic auth +- 772c5f1c: Fix: fetchHookData with usePosts and throwIfNotFound set to false will crash the application if no results are found + +## 1.1.2-next.1 + +### Patch Changes + +- 772c5f1c: Fix: fetchHookData with usePosts and throwIfNotFound set to false will crash the application if no results are found + +## 1.1.2-next.0 + +### Patch Changes + +- 15189a03: Adding support for basic auth + +## 1.1.1 + +### Patch Changes + +- de501ff7: Fix an issue for images without width or height + +## 1.1.0 + +### Minor Changes + +- 4275962b: Introducing `usePostOrPosts`. +- df3e65ce: Introduces `SafeHtml` and `HtmlDecoder` components. +- e9064d69: Introducing the `useSeo` hook. +- d3ec9d83: Introduces the `decodeHtmlSpecialChars` function. + +### Patch Changes + +- e6a0c231: Lower compilation target +- 24f8a99f: Fix theme.json handling in `useBlockColors` and `useBlockTypography`. + + Thanks @riccardodicurti @dhamibirendra for [the bug report](https://github.com/10up/headstartwp/issues/541). + +- bb39a603: Fixes useSearch error when Yoast SEO plugin is deactivated. +- 569662b6: Improves the Next.js preview cookie handling and fixes a bug where the locale was not properly being passed from WP when previewing. + + First of all, it sets the preview cookie to expire within 5 minutes which aligns with the JWT token expiration. + + Secondly, it will narrow the cookie to the post path being previewed so that `context.preview` is not true for other paths and thus avoiding bypassing getStaticProps until the cookies are cleared (either expires or the browser closes). + +- 56ddf9be: Fix theme.json handling for block settings +- 1494a332: Further Optimize next.js props by removing yoast seo bloat. + ## 1.1.0-next.5 ### Minor Changes diff --git a/packages/core/package.json b/packages/core/package.json index d89680d86..c467645b8 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@headstartwp/core", - "version": "1.1.0-next.5", + "version": "1.1.2", "description": "`@headstartwp/core` is the core package that houses framework-agnostic components and utilities for building headless sites with WordPress.", "homepage": "https://github.com/10up/headstartwp/blob/develop/packages/core/README.md", "license": "MIT", diff --git a/packages/core/src/data/api/fetch-utils.ts b/packages/core/src/data/api/fetch-utils.ts index b249b49d8..141d2b08e 100644 --- a/packages/core/src/data/api/fetch-utils.ts +++ b/packages/core/src/data/api/fetch-utils.ts @@ -48,12 +48,6 @@ export const apiGet = async ( args: { [index: string]: any } = {}, burstCache = false, ) => { - const headers = getAuthHeader(); - - if (headers) { - args.headers = headers; - } - const queryArgs = burstCache ? { cacheTime: new Date().getTime(), diff --git a/packages/core/src/data/strategies/AbstractFetchStrategy.ts b/packages/core/src/data/strategies/AbstractFetchStrategy.ts index 6d3136fc3..22711bb39 100644 --- a/packages/core/src/data/strategies/AbstractFetchStrategy.ts +++ b/packages/core/src/data/strategies/AbstractFetchStrategy.ts @@ -224,6 +224,27 @@ export abstract class AbstractFetchStrategy = {}) { + let bearerAuthHeader = ''; + if (options.bearerToken) { + bearerAuthHeader = `Bearer ${options.bearerToken}`; + } + + const basicAuthUsername = + process.env.WP_BASIC_AUTH_USERNAME ?? process.env.NEXT_PUBLIC_WP_BASIC_AUTH_USERNAME; + const basicAuthPassword = + process.env.WP_BASIC_AUTH_PASSWORD ?? process.env.NEXT_PUBLIC_WP_BASIC_AUTH_PASSWORD; + + if (basicAuthUsername && basicAuthPassword) { + const basicAuth = `Basic ${btoa(`${basicAuthUsername}:${basicAuthPassword}`)}`; + if (bearerAuthHeader) { + return `${basicAuth}, ${bearerAuthHeader}`; + } + return basicAuth; + } + return bearerAuthHeader; + } + /** * The default fetcher function * @@ -245,9 +266,13 @@ export abstract class AbstractFetchStrategy = { - result: result.json, + result: resultData, pageInfo: { totalPages: Number(result.headers['x-wp-totalpages']) || 0, totalItems: Number(result.headers['x-wp-total']) || 0, diff --git a/packages/core/src/data/strategies/SinglePostFetchStrategy.ts b/packages/core/src/data/strategies/SinglePostFetchStrategy.ts index bff3ca99f..fe36bf9d4 100644 --- a/packages/core/src/data/strategies/SinglePostFetchStrategy.ts +++ b/packages/core/src/data/strategies/SinglePostFetchStrategy.ts @@ -279,6 +279,8 @@ export class SinglePostFetchStrategy< options.bearerToken = params.authToken; } + const authHeader = this.getAuthHeader(options); + let error; if (params.revision && params.id) { try { @@ -286,7 +288,7 @@ export class SinglePostFetchStrategy< `${this.baseURL}${this.getEndpoint()}/revisions?per_page=1`, { headers: { - Authorization: `Bearer ${options.bearerToken}`, + Authorization: authHeader, }, }, burstCache, diff --git a/packages/core/src/data/strategies/__tests__/PostOrPostsFetchStrategy.ts b/packages/core/src/data/strategies/__tests__/PostOrPostsFetchStrategy.ts index b7e2fb993..9d12a92a3 100644 --- a/packages/core/src/data/strategies/__tests__/PostOrPostsFetchStrategy.ts +++ b/packages/core/src/data/strategies/__tests__/PostOrPostsFetchStrategy.ts @@ -243,7 +243,7 @@ describe('PostOrPostsFetchStrategy', () => { useWordPressPlugin: true, }); - const params = fetchStrategy.getParamsFromURL('/page/2'); + const params = fetchStrategy.getParamsFromURL('/page/1'); const response = await fetchStrategy.fetcher( '', merge(params, { priority: 'single', routeMatchStrategy: 'archive' }), @@ -257,7 +257,7 @@ describe('PostOrPostsFetchStrategy', () => { useWordPressPlugin: true, }); - let params = fetchStrategy.getParamsFromURL('/page/2'); + let params = fetchStrategy.getParamsFromURL('/page/1'); let response = await fetchStrategy.fetcher( '', merge(params, { priority: 'single', routeMatchStrategy: 'single' }), @@ -265,7 +265,7 @@ describe('PostOrPostsFetchStrategy', () => { expect(response.result.isSingle).toBeFalsy(); expect(response.result.isArchive).toBeTruthy(); - params = fetchStrategy.getParamsFromURL('/page/2'); + params = fetchStrategy.getParamsFromURL('/page/1'); response = await fetchStrategy.fetcher( '', merge(params, { priority: 'archive', routeMatchStrategy: 'single' }), diff --git a/packages/core/src/data/strategies/__tests__/SinglePostFetchStrategy.ts b/packages/core/src/data/strategies/__tests__/SinglePostFetchStrategy.ts index 76173a0a8..9c7a59c59 100644 --- a/packages/core/src/data/strategies/__tests__/SinglePostFetchStrategy.ts +++ b/packages/core/src/data/strategies/__tests__/SinglePostFetchStrategy.ts @@ -681,4 +681,66 @@ describe('SinglePostFetchStrategy', () => { result: {}, }); }); + + it('handles basic auth', async () => { + const samplePost = { title: 'test', id: 1, link: '/2021/10/post-name' }; + const sampleHeaders = { + 'x-wp-totalpages': 1, + 'x-wp-total': 1, + }; + + apiGetMock.mockResolvedValue({ + headers: sampleHeaders, + json: [samplePost], + }); + + process.env.WP_BASIC_AUTH_PASSWORD = 'test'; + process.env.WP_BASIC_AUTH_USERNAME = 'admin'; + + const params = fetchStrategy.getParamsFromURL('/2021/10/post-name'); + await fetchStrategy.fetcher(fetchStrategy.buildEndpointURL(params), params); + + expect(apiGetMock).toHaveBeenNthCalledWith( + 1, + '/wp-json/wp/v2/posts?slug=post-name', + { + headers: { + Authorization: 'Basic YWRtaW46dGVzdA==', + }, + }, + false, + ); + }); + + it('handles basic auth and bearer token', async () => { + const samplePost = { title: 'test', id: 1, link: '/2021/10/post-name' }; + const sampleHeaders = { + 'x-wp-totalpages': 1, + 'x-wp-total': 1, + }; + + apiGetMock.mockResolvedValue({ + headers: sampleHeaders, + json: [samplePost], + }); + + process.env.WP_BASIC_AUTH_PASSWORD = 'test'; + process.env.WP_BASIC_AUTH_USERNAME = 'admin'; + + const params = fetchStrategy.getParamsFromURL('/2021/10/post-name'); + await fetchStrategy.fetcher(fetchStrategy.buildEndpointURL(params), params, { + bearerToken: 'bearer token', + }); + + expect(apiGetMock).toHaveBeenNthCalledWith( + 1, + '/wp-json/wp/v2/posts?slug=post-name', + { + headers: { + Authorization: 'Basic YWRtaW46dGVzdA==, Bearer bearer token', + }, + }, + false, + ); + }); }); diff --git a/packages/core/src/react/blocks/ImageBlock.tsx b/packages/core/src/react/blocks/ImageBlock.tsx index 1e5e15c44..b21397720 100644 --- a/packages/core/src/react/blocks/ImageBlock.tsx +++ b/packages/core/src/react/blocks/ImageBlock.tsx @@ -41,6 +41,8 @@ export function ImageBlock({ } const { src, alt, width: imgNodeWidth, height: imgNodeHeight } = imgNode.attribs; + const imageWidth = width ?? imgNodeWidth; + const imageHeight = height ?? imgNodeHeight; return ( {children} diff --git a/packages/core/src/react/hooks/__tests__/useFetchAppSettings.tsx b/packages/core/src/react/hooks/__tests__/useFetchAppSettings.tsx index ec2332791..c5c8e9ff3 100644 --- a/packages/core/src/react/hooks/__tests__/useFetchAppSettings.tsx +++ b/packages/core/src/react/hooks/__tests__/useFetchAppSettings.tsx @@ -1,7 +1,9 @@ -import { renderHook } from '@testing-library/react'; +import { renderHook, waitFor } from '@testing-library/react'; import { expectTypeOf } from 'expect-type'; import { AppEntity, EndpointParams } from '../../../data'; import { useFetchAppSettings } from '../useFetchAppSettings'; +import * as useFetchModule from '../useFetch'; +import { mockUseFetchErrorResponse } from '../mocks'; describe('useFetchAppSettings types', () => { it('allows overriding types', () => { @@ -23,4 +25,27 @@ describe('useFetchAppSettings types', () => { | undefined >(); }); + + it('handles response if has error or there is no data', async () => { + const spyUseFetch = jest + .spyOn(useFetchModule, 'useFetch') + .mockReturnValueOnce(mockUseFetchErrorResponse); + const { result } = renderHook(() => useFetchAppSettings({ includeCustomSettings: true })); + + const expectedKeys = ['error', 'loading', 'data', 'isMainQuery']; + const returnedKeys = Object.keys(result.current); + const missingKeys = returnedKeys.filter((key) => !expectedKeys.includes(key)); + + await waitFor(() => { + expect(missingKeys).toHaveLength(0); + expect(spyUseFetch).toHaveBeenCalledTimes(1); + expect(result.current.error).toBe('Not found'); + expect(result.current.loading).toBe(true); + expect(() => result.current.data).not.toThrow(); + expect(() => result.current.data?.posts).toThrow(); + expect(result.current.isMainQuery).toBe(true); + }); + + spyUseFetch.mockRestore(); + }); }); diff --git a/packages/core/src/react/hooks/__tests__/useFetchPost.tsx b/packages/core/src/react/hooks/__tests__/useFetchPost.tsx index 2ddcb0f4e..cb089a064 100644 --- a/packages/core/src/react/hooks/__tests__/useFetchPost.tsx +++ b/packages/core/src/react/hooks/__tests__/useFetchPost.tsx @@ -5,6 +5,8 @@ import { DRAFT_POST_ID, VALID_AUTH_TOKEN } from '../../../../test/server'; import { PostEntity, PostParams } from '../../../data'; import { SettingsProvider } from '../../provider'; import { useFetchPost } from '../useFetchPost'; +import * as useFetchModule from '../useFetch'; +import { mockUseFetchErrorResponse } from '../mocks'; describe('useFetchPost', () => { const wrapper = ({ children }) => { @@ -43,6 +45,31 @@ describe('useFetchPost', () => { ); }); + it('handles response if has error or there is no data', async () => { + const spyUseFetch = jest + .spyOn(useFetchModule, 'useFetch') + .mockReturnValueOnce(mockUseFetchErrorResponse); + const { result } = renderHook(() => useFetchPost({}), { + wrapper, + }); + + const expectedKeys = ['error', 'loading', 'data', 'isMainQuery']; + const returnedKeys = Object.keys(result.current); + const missingKeys = returnedKeys.filter((key) => !expectedKeys.includes(key)); + + await waitFor(() => { + expect(missingKeys).toHaveLength(0); + expect(spyUseFetch).toHaveBeenCalledTimes(1); + expect(result.current.error).toBe('Not found'); + expect(result.current.loading).toBe(false); + expect(() => result.current.data).not.toThrow(); + expect(() => result.current.data?.post.title).toThrow(); + expect(result.current.isMainQuery).toBe(true); + }); + + spyUseFetch.mockRestore(); + }); + it('fetch by id', async () => { const { result } = renderHook(() => useFetchPost({ id: 64 }), { wrapper, diff --git a/packages/core/src/react/hooks/__tests__/useFetchPostOrPosts.tsx b/packages/core/src/react/hooks/__tests__/useFetchPostOrPosts.tsx index 00814d1db..c712bfae0 100644 --- a/packages/core/src/react/hooks/__tests__/useFetchPostOrPosts.tsx +++ b/packages/core/src/react/hooks/__tests__/useFetchPostOrPosts.tsx @@ -6,6 +6,8 @@ import { useFetchPostOrPosts } from '../useFetchPostOrPosts'; import { PostEntity, PostOrPostsParams } from '../../../data'; import { useFetchPost } from '../useFetchPost'; import { useFetchPosts } from '../useFetchPosts'; +import * as useFetchModule from '../useFetch'; +import { mockUseFetchErrorResponse } from '../mocks'; describe('useFetchPostOrPosts', () => { const wrapper = ({ children }) => { @@ -75,6 +77,33 @@ describe('useFetchPostOrPosts', () => { }); }); + it('handles response if has error or there is no data', async () => { + const spyUseFetch = jest + .spyOn(useFetchModule, 'useFetch') + .mockReturnValueOnce(mockUseFetchErrorResponse); + const { result } = renderHook(() => useFetchPostOrPosts({}), { + wrapper, + }); + const expectedKeys = ['error', 'loading', 'isArchive', 'isSingle', 'data', 'isMainQuery']; + const returnedKeys = Object.keys(result.current); + const missingKeys = returnedKeys.filter((key) => !expectedKeys.includes(key)); + + await waitFor(() => { + expect(missingKeys).toHaveLength(0); + expect(spyUseFetch).toHaveBeenCalledTimes(3); // #1 useFetch, #2 useFetchPost, #3 useFetchPosts + expect(result.current.error).toBe('Not found'); + expect(result.current.loading).toBe(false); + expect(result.current.isArchive).toBe(false); + expect(result.current.isSingle).toBe(false); + expect(() => result.current.data).not.toThrow(); + expect(() => result.current.data?.post!.title).toThrow(); + expect(() => result.current.data?.posts![0].title).toThrow(); + expect(result.current.isMainQuery).toBe(true); + }); + + spyUseFetch.mockRestore(); + }); + it('populates internal swr cache (single)', async () => { const p: PostOrPostsParams = { archive: { taxonomy: 'category' }, diff --git a/packages/core/src/react/hooks/__tests__/useFetchPosts.tsx b/packages/core/src/react/hooks/__tests__/useFetchPosts.tsx index b29da7aab..3d6a8c492 100644 --- a/packages/core/src/react/hooks/__tests__/useFetchPosts.tsx +++ b/packages/core/src/react/hooks/__tests__/useFetchPosts.tsx @@ -6,6 +6,8 @@ import { PostEntity, PostsArchiveParams } from '../../../data'; import { SettingsProvider } from '../../provider'; import { useFetchPosts } from '../useFetchPosts'; import { setHeadlessConfig } from '../../../utils'; +import * as useFetchModule from '../useFetch'; +import { mockUseFetchErrorResponse } from '../mocks'; describe('useFetchPosts', () => { const wrapper = ({ children }) => { @@ -40,6 +42,33 @@ describe('useFetchPosts', () => { }); }); + it('handles response if has error or there is no data', async () => { + const spyUseFetch = jest + .spyOn(useFetchModule, 'useFetch') + .mockReturnValueOnce(mockUseFetchErrorResponse); + const { result } = renderHook(() => useFetchPosts({}), { + wrapper, + }); + + const expectedKeys = ['error', 'loading', 'pageType', 'data', 'isMainQuery']; + const returnedKeys = Object.keys(result.current); + const missingKeys = returnedKeys.filter((key) => !expectedKeys.includes(key)); + + await waitFor(() => { + expect(missingKeys).toHaveLength(0); + expect(spyUseFetch).toHaveBeenCalledTimes(1); + expect(result.current.error).toBe('Not found'); + expect(result.current.loading).toBe(true); + expect(() => result.current.data).not.toThrow(); + expect(() => result.current.data?.posts[0].title).toThrow(); + expect(() => result.current.data?.pageInfo[0].title).toThrow(); + expect(() => result.current.data?.queriedObject[0].title).toThrow(); + expect(result.current.isMainQuery).toBe(true); + }); + + spyUseFetch.mockRestore(); + }); + it('returns queried object for category archives', async () => { const { result } = renderHook( () => @@ -189,6 +218,52 @@ describe('useFetchPosts', () => { }); }); + it('does not crash when not found but throwIfNotFound is set to false', async () => { + const { result } = renderHook( + () => + useFetchPosts( + { taxonomy: 'category' }, + { + fetchStrategyOptions: { + throwIfNotFound: false, + }, + }, + '/i-do-not-exist', + ), + { + wrapper, + }, + ); + + await waitFor(() => { + expect(result.current.error).toBeFalsy(); + expect(result.current.data?.posts.length).toBe(0); + }); + }); + + it('does not crash when invalid page param when throwIfNotFound is set to false', async () => { + const { result } = renderHook( + () => + useFetchPosts( + { taxonomy: 'category' }, + { + fetchStrategyOptions: { + throwIfNotFound: false, + }, + }, + '/news/page/10', + ), + { + wrapper, + }, + ); + + await waitFor(() => { + expect(result.current.error).toBeFalsy(); + expect(result.current.data?.posts.length).toBe(0); + }); + }); + describe('useFetchPosts types', () => { it('allows overriding types', () => { interface Book extends PostEntity { diff --git a/packages/core/src/react/hooks/__tests__/useFetchSearch.tsx b/packages/core/src/react/hooks/__tests__/useFetchSearch.tsx index d90de9a7c..bcb021cbb 100644 --- a/packages/core/src/react/hooks/__tests__/useFetchSearch.tsx +++ b/packages/core/src/react/hooks/__tests__/useFetchSearch.tsx @@ -6,8 +6,10 @@ import { PostEntity, PostsArchiveParams } from '../../../data'; import { SettingsProvider } from '../../provider'; import { useFetchSearch } from '../useFetchSearch'; import { setHeadlessConfig } from '../../../utils'; +import * as useFetchModule from '../useFetch'; +import { mockUseFetchErrorResponse } from '../mocks'; -describe('useFetchPosts', () => { +describe('useFetchSearch', () => { const wrapper = ({ children }) => { return {children}; }; @@ -29,6 +31,33 @@ describe('useFetchPosts', () => { }); }); + it('handles response if has error or there is no data', async () => { + const spyUseFetch = jest + .spyOn(useFetchModule, 'useFetch') + .mockReturnValueOnce(mockUseFetchErrorResponse); + const { result } = renderHook(() => useFetchSearch({}), { + wrapper, + }); + + const expectedKeys = ['error', 'loading', 'data', 'isMainQuery']; + const returnedKeys = Object.keys(result.current); + const missingKeys = returnedKeys.filter((key) => !expectedKeys.includes(key)); + + await waitFor(() => { + expect(missingKeys).toHaveLength(0); + expect(spyUseFetch).toHaveBeenCalledTimes(1); + expect(result.current.error).toBe('Not found'); + expect(result.current.loading).toBe(true); + expect(() => result.current.data).not.toThrow(); + expect(() => result.current.data?.posts[0].title).toThrow(); + expect(() => result.current.data?.pageInfo[0].title).toThrow(); + expect(() => result.current.data?.queriedObject[0].title).toThrow(); + expect(result.current.isMainQuery).toBe(true); + }); + + spyUseFetch.mockRestore(); + }); + it('fetches data properly', async () => { const { result } = renderHook(() => useFetchSearch({ per_page: 2 }, {}, '/ipsum'), { wrapper, diff --git a/packages/core/src/react/hooks/__tests__/useFetchTerms.tsx b/packages/core/src/react/hooks/__tests__/useFetchTerms.tsx index 5264ca67e..a87c84183 100644 --- a/packages/core/src/react/hooks/__tests__/useFetchTerms.tsx +++ b/packages/core/src/react/hooks/__tests__/useFetchTerms.tsx @@ -1,7 +1,9 @@ -import { renderHook } from '@testing-library/react'; +import { renderHook, waitFor } from '@testing-library/react'; import { expectTypeOf } from 'expect-type'; import { TaxonomyArchiveParams, TermEntity } from '../../../data'; import { useFetchTerms } from '../useFetchTerms'; +import * as useFetchModule from '../useFetch'; +import { mockUseFetchErrorResponse } from '../mocks'; describe('useFetchTerms types', () => { it('allows overriding types', () => { @@ -22,4 +24,28 @@ describe('useFetchTerms types', () => { | undefined >(); }); + + it('handles response if has error or there is no data', async () => { + const spyUseFetch = jest + .spyOn(useFetchModule, 'useFetch') + .mockReturnValueOnce(mockUseFetchErrorResponse); + const { result } = renderHook(() => useFetchTerms({ includeCustomSettings: true })); + + const expectedKeys = ['error', 'loading', 'data', 'isMainQuery']; + const returnedKeys = Object.keys(result.current); + const missingKeys = returnedKeys.filter((key) => !expectedKeys.includes(key)); + + await waitFor(() => { + expect(missingKeys).toHaveLength(0); + expect(spyUseFetch).toHaveBeenCalledTimes(1); + expect(result.current.error).toBe('Not found'); + expect(result.current.loading).toBe(true); + expect(() => result.current.data).not.toThrow(); + expect(() => result.current.data?.terms[0].title).toThrow(); + expect(() => result.current.data?.pageInfo[0].title).toThrow(); + expect(result.current.isMainQuery).toBe(true); + }); + + spyUseFetch.mockRestore(); + }); }); diff --git a/packages/core/src/react/hooks/mocks.ts b/packages/core/src/react/hooks/mocks.ts new file mode 100644 index 000000000..46fecc3c0 --- /dev/null +++ b/packages/core/src/react/hooks/mocks.ts @@ -0,0 +1,9 @@ +export const mockUseFetchErrorResponse = { + error: 'Not found', + params: {}, + data: undefined, + isMainQuery: true, + mutate: jest.fn(), + isLoading: false, + isValidating: false, +}; diff --git a/packages/core/test/server-handlers.ts b/packages/core/test/server-handlers.ts index 52c6d047e..24babafcb 100644 --- a/packages/core/test/server-handlers.ts +++ b/packages/core/test/server-handlers.ts @@ -47,6 +47,7 @@ const handlers = [ const search = query.get('search'); const slug = query.get('slug'); const perPage = Number(query.get('per_page') || 10); + const page = Number(query.get('page') || 1); const category = query.get('categories'); const author = query.get('author'); const embed = query.get('_embed'); @@ -107,8 +108,21 @@ const handlers = [ const totalResults = results.length; + if ((page - 1) * perPage > totalResults) { + return res( + ctx.json({ + code: 'rest_post_invalid_page_number', + message: + 'The page number requested is larger than the number of pages available.', + data: { + status: 400, + }, + }), + ); + } + if (perPage) { - results = results.slice(0, perPage); + results = results.slice((page - 1) * perPage, perPage); } return res( diff --git a/packages/next/CHANGELOG.md b/packages/next/CHANGELOG.md index 2ee83604f..aeb38c321 100644 --- a/packages/next/CHANGELOG.md +++ b/packages/next/CHANGELOG.md @@ -1,5 +1,88 @@ # @headstartwp/next +## 1.1.6 + +### Patch Changes + +- 5bf90ccd: Fix loading of the headless.config.js file to prevent injecting it twice. + +## 1.1.6-next.0 + +### Patch Changes + +- 5bf90ccd: Fix loading of the headless.config.js file to prevent injecting it twice. + +## 1.1.5 + +### Patch Changes + +- 556aba2b: Fix previews for custom post types + +## 1.1.4 + +### Patch Changes + +- Updated dependencies [15189a03] +- Updated dependencies [772c5f1c] + - @headstartwp/core@1.1.2 + +## 1.1.4-next.0 + +### Patch Changes + +- Updated dependencies [15189a03] + - @headstartwp/core@1.1.2-next.0 + +## 1.1.3 + +### Patch Changes + +- b07d4f8e: Fix previews + +## 1.1.2 + +### Patch Changes + +- 1922ffbd: Fix bug where previews were not working with locales as the redirect path for the preview cookie was incorrect. + +## 1.1.1 + +### Patch Changes + +- de501ff7: Fix an issue for images without width or height +- Updated dependencies [de501ff7] + - @headstartwp/core@1.1.1 + +## 1.1.0 + +### Minor Changes + +- 4275962b: Introducing `usePostOrPosts`. +- 569662b6: Improves the Next.js preview cookie handling and fixes a bug where the locale was not properly being passed from WP when previewing. + + First of all, it sets the preview cookie to expire within 5 minutes which aligns with the JWT token expiration. + + Secondly, it will narrow the cookie to the post path being previewed so that `context.preview` is not true for other paths and thus avoiding bypassing getStaticProps until the cookies are cleared (either expires or the browser closes). + +### Patch Changes + +- e6a0c231: Lower compilation target +- 232f4e68: Fix: only convertUrls if url starts with sourceUrl +- 90d5fa3c: Fix typo in files to be published to npm +- 1494a332: Further Optimize next.js props by removing yoast seo bloat. +- 866551f2: Fix an annoying bug that would require deleting the .next/cache folder after changing headless.config.js or .env files. Now you only need to restart the next.js server after changing those files. +- Updated dependencies [e6a0c231] +- Updated dependencies [24f8a99f] +- Updated dependencies [bb39a603] +- Updated dependencies [4275962b] +- Updated dependencies [569662b6] +- Updated dependencies [df3e65ce] +- Updated dependencies [e9064d69] +- Updated dependencies [56ddf9be] +- Updated dependencies [1494a332] +- Updated dependencies [d3ec9d83] + - @headstartwp/core@1.1.0 + ## 1.1.0-next.3 ### Minor Changes diff --git a/packages/next/package.json b/packages/next/package.json index a0da1e892..ca49f51d7 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "@headstartwp/next", - "version": "1.1.0-next.3", + "version": "1.1.6", "description": "`@headstartwp/next` is the Next.js bindings for the headless framework.", "homepage": "https://github.com/10up/headstartwp/blob/develop/packages/next/README.md", "license": "MIT", @@ -49,8 +49,7 @@ }, "dependencies": { "deepmerge": "^4.3.1", - "@headstartwp/core": "^1.1.0-next.4", - "modify-source-webpack-plugin": "^4.1.0", + "@headstartwp/core": "^1.1.2", "loader-utils": "^3.2.0", "schema-utils": "^4.0.0" }, diff --git a/packages/next/src/components/ImageComponent.tsx b/packages/next/src/components/ImageComponent.tsx index 254eb1b68..5b0daaa81 100644 --- a/packages/next/src/components/ImageComponent.tsx +++ b/packages/next/src/components/ImageComponent.tsx @@ -102,7 +102,7 @@ export function ImageComponent({ src, alt, width, height, children, style, loade } if (!width || !height) { - {alt; + return {alt; } return ( diff --git a/packages/next/src/config/plugins/ModifySourcePlugin/ModifySourcePlugin.ts b/packages/next/src/config/plugins/ModifySourcePlugin/ModifySourcePlugin.ts new file mode 100644 index 000000000..5d5f65694 --- /dev/null +++ b/packages/next/src/config/plugins/ModifySourcePlugin/ModifySourcePlugin.ts @@ -0,0 +1,139 @@ +import type { Compiler, NormalModule, Compilation } from 'webpack'; + +import { AbstractOperation, Operation } from './operations'; + +const { validate } = require('schema-utils'); + +export interface Rule { + test: RegExp | ((module: NormalModule, compilation: Compilation) => boolean); + operations?: AbstractOperation[]; +} + +export type Options = { + debug?: boolean; + rules: Rule[]; + constants?: Record; +}; + +const validationSchema = { + type: 'object', + additionalProperties: false, + properties: { + rules: { + type: 'array', + items: { + type: 'object', + additionalProperties: false, + properties: { + test: { + anyOf: [{ instanceof: 'Function' }, { instanceof: 'RegExp' }], + }, + operations: { + type: 'array', + items: { + type: 'object', + }, + }, + }, + }, + }, + constants: { + type: 'object', + }, + debug: { + type: 'boolean', + }, + }, +}; + +const PLUGIN_NAME = 'ModifySourcePlugin'; + +export class ModifySourcePlugin { + constructor(protected readonly options: Options) { + validate(validationSchema, options, { + name: PLUGIN_NAME, + }); + } + + public apply(compiler: Compiler): void { + const { rules, debug, constants = {} } = this.options; + + compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => { + const modifiedModules: (string | number)[] = []; + + const tapCallback = (_: any, normalModule: NormalModule) => { + const userRequest = normalModule.userRequest || ''; + + const startIndex = + userRequest.lastIndexOf('!') === -1 ? 0 : userRequest.lastIndexOf('!') + 1; + + const moduleRequest = userRequest.substring(startIndex).replace(/\\/g, '/'); + + if (modifiedModules.includes(moduleRequest)) { + return; + } + + rules.forEach((ruleOptions) => { + const { test } = ruleOptions; + const isMatched = (() => { + if (typeof test === 'function' && test(normalModule, compilation)) { + return true; + } + + return test instanceof RegExp && test.test(moduleRequest); + })(); + + if (isMatched) { + type NormalModuleLoader = { + loader: string; + options: any; + ident?: string; + type?: string; + }; + + const serializableOperations = ruleOptions.operations?.map((op) => + Operation.makeSerializable(op), + ); + + let loader; + + try { + loader = require.resolve('./loader.js'); + } catch (e) { + loader = require.resolve('../build/loader.js'); + } + + (normalModule.loaders as NormalModuleLoader[]).push({ + loader, + options: { + moduleRequest, + operations: serializableOperations, + constants, + }, + }); + + modifiedModules.push(moduleRequest); + + if (debug) { + // eslint-disable-next-line no-console + console.log(`\n[${PLUGIN_NAME}] Use loader for "${moduleRequest}".`); + } + } + }); + }; + + const NormalModule = compiler.webpack?.NormalModule; + const isNormalModuleAvailable = + Boolean(NormalModule) && Boolean(NormalModule.getCompilationHooks); + + if (isNormalModuleAvailable) { + NormalModule.getCompilationHooks(compilation).beforeLoaders.tap( + PLUGIN_NAME, + tapCallback, + ); + } else { + compilation.hooks.normalModuleLoader.tap(PLUGIN_NAME, tapCallback); + } + }); + } +} diff --git a/packages/next/src/config/plugins/ModifySourcePlugin/index.ts b/packages/next/src/config/plugins/ModifySourcePlugin/index.ts new file mode 100644 index 000000000..7787b76c9 --- /dev/null +++ b/packages/next/src/config/plugins/ModifySourcePlugin/index.ts @@ -0,0 +1,2 @@ +export * from './ModifySourcePlugin'; +export * from './operations'; diff --git a/packages/next/src/config/plugins/ModifySourcePlugin/loader.ts b/packages/next/src/config/plugins/ModifySourcePlugin/loader.ts new file mode 100644 index 000000000..db9e40cf3 --- /dev/null +++ b/packages/next/src/config/plugins/ModifySourcePlugin/loader.ts @@ -0,0 +1,63 @@ +import path from 'path'; + +import { Operation, SerializableOperation } from './operations'; + +const { validate } = require('schema-utils'); + +const schema = { + type: 'object', + properties: { + operations: { + type: 'array', + items: { + type: 'object', + }, + }, + moduleRequest: { + type: 'string', + }, + constants: { + type: 'object', + }, + }, + additionalProperties: false, +}; + +interface LoaderOptions { + operations: SerializableOperation[]; + moduleRequest: string; + constants: Record; +} + +interface modifyModuleSourceLoader { + getOptions: () => LoaderOptions; +} + +// eslint-disable-next-line @typescript-eslint/no-redeclare +export default function modifyModuleSourceLoader( + this: modifyModuleSourceLoader, + source: string, +): string { + const options: LoaderOptions = this.getOptions(); + + validate(schema, options, { + name: 'ModifySourcePlugin webpack loader', + }); + + const cleanPath = options.moduleRequest.split('?')[0]; + const fileName = path.basename(cleanPath); + + if (source.includes('__setHeadstartWPConfig')) { + return source; + } + + return options.operations.reduce((sourceText, serializableOp) => { + const operation = Operation.fillConstants(Operation.fromSerializable(serializableOp), { + ...options.constants, + FILE_PATH: cleanPath, + FILE_NAME: fileName, + }); + + return Operation.apply(sourceText, operation); + }, source); +} diff --git a/packages/next/src/config/plugins/ModifySourcePlugin/operations/AbstractOperation.ts b/packages/next/src/config/plugins/ModifySourcePlugin/operations/AbstractOperation.ts new file mode 100644 index 000000000..9cb4bd99c --- /dev/null +++ b/packages/next/src/config/plugins/ModifySourcePlugin/operations/AbstractOperation.ts @@ -0,0 +1,15 @@ +export type SerializableProperties = { + [K in keyof T as T[K] extends string ? K : never]: T[K] extends string ? T[K] : never; +}; + +export type SerializableOperation = { + operationName: string; +} & { + [K in keyof T as T[K] extends string ? K : never]: T[K] extends string ? T[K] : never; +}; + +export abstract class AbstractOperation { + public abstract getSerializableProperties(): string[]; + + public abstract getTextProperties(): string[]; +} diff --git a/packages/next/src/config/plugins/ModifySourcePlugin/operations/ConcatOperation.ts b/packages/next/src/config/plugins/ModifySourcePlugin/operations/ConcatOperation.ts new file mode 100644 index 000000000..77a5b3a81 --- /dev/null +++ b/packages/next/src/config/plugins/ModifySourcePlugin/operations/ConcatOperation.ts @@ -0,0 +1,27 @@ +import { AbstractOperation } from './AbstractOperation'; + +export enum ConcatOperationType { + 'start' = 'start', + 'end' = 'end', +} + +export class ConcatOperation extends AbstractOperation { + constructor( + public readonly type: keyof typeof ConcatOperationType, + public readonly value: string, + ) { + super(); + } + + public getSerializableProperties(): (keyof this & string)[] { + return ['type', 'value']; + } + + public getTextProperties(): (keyof this & string)[] { + return ['value']; + } + + public static getAllowedTypes(): ConcatOperationType[] { + return [ConcatOperationType.start, ConcatOperationType.end]; + } +} diff --git a/packages/next/src/config/plugins/ModifySourcePlugin/operations/Operation.ts b/packages/next/src/config/plugins/ModifySourcePlugin/operations/Operation.ts new file mode 100644 index 000000000..d488b93fb --- /dev/null +++ b/packages/next/src/config/plugins/ModifySourcePlugin/operations/Operation.ts @@ -0,0 +1,120 @@ +import { + AbstractOperation, + SerializableOperation, + SerializableProperties, +} from './AbstractOperation'; +import { ConcatOperation } from './ConcatOperation'; +import { ReplaceOperation } from './ReplaceOperation'; + +function isSerializableOfOperation( + serializable: SerializableOperation, + operation: { new (...args: any[]): T }, +): serializable is SerializableOperation { + return serializable.operationName === operation.name; +} + +function throwUnknownOperationType(op: AbstractOperation, opType: string): void { + const allowedTypes = + op instanceof ConcatOperation + ? ConcatOperation.getAllowedTypes() + : ReplaceOperation.getAllowedTypes(); + + throw new Error( + `Incorrect operation type '${opType}' for ${ + op.constructor.name + }. Allowed types: '${allowedTypes.join("', '")}'.`, + ); +} + +export class Operation { + public static makeSerializable(op: T): SerializableOperation { + const propertyValues = op.getSerializableProperties().reduce((acc, val) => { + return { + ...acc, + [val]: op[val as keyof T], + }; + }, {} as SerializableProperties); + + return { + operationName: op.constructor.name, + ...propertyValues, + }; + } + + public static fromSerializable(serializable: SerializableOperation): AbstractOperation { + if (isSerializableOfOperation(serializable, ConcatOperation)) { + const { type, value } = serializable; + + return new ConcatOperation(type, value); + } + + if (isSerializableOfOperation(serializable, ReplaceOperation)) { + const { type, searchValue, replaceValue } = serializable; + + return new ReplaceOperation(type, searchValue, replaceValue); + } + + throw new Error(`Incorrect serializable provided: ${JSON.stringify(serializable)}`); + } + + public static fillConstants< + T extends AbstractOperation, + TConstants extends Record, + >(operation: T, constants: TConstants): T { + const filledTextProps = operation.getTextProperties().reduce((acc, propName) => { + let propValue = operation[propName as keyof T] as string; + + Object.keys(constants).forEach((constant) => { + propValue = propValue.replace( + new RegExp(`\\$${constant}`, 'g'), + String(constants[constant]), + ); + }); + + return { + ...acc, + [propName]: propValue, + }; + }, {}); + + const mergedObject = { + ...Operation.makeSerializable(operation), + ...filledTextProps, + }; + + return Operation.fromSerializable(mergedObject) as T; + } + + public static apply(src: string, operation: AbstractOperation): string { + if (operation instanceof ConcatOperation) { + switch (operation.type) { + case 'start': + return operation.value + src; + + case 'end': + return src + operation.value; + + default: + throwUnknownOperationType(operation, operation.type); + } + } + + if (operation instanceof ReplaceOperation) { + switch (operation.type) { + case 'once': + return src.replace(operation.searchValue, operation.replaceValue); + + case 'all': + return src.replace( + new RegExp(operation.searchValue, 'g'), + operation.replaceValue, + ); + + default: + throwUnknownOperationType(operation, operation.type); + } + } + + throw new Error(`Unknown operation instance: ${operation.constructor.name}`); + } +} diff --git a/packages/next/src/config/plugins/ModifySourcePlugin/operations/ReplaceOperation.ts b/packages/next/src/config/plugins/ModifySourcePlugin/operations/ReplaceOperation.ts new file mode 100644 index 000000000..38a56a793 --- /dev/null +++ b/packages/next/src/config/plugins/ModifySourcePlugin/operations/ReplaceOperation.ts @@ -0,0 +1,28 @@ +import { AbstractOperation } from './AbstractOperation'; + +export enum ReplaceOperationType { + 'once' = 'once', + 'all' = 'all', +} + +export class ReplaceOperation extends AbstractOperation { + constructor( + public readonly type: keyof typeof ReplaceOperationType, + public readonly searchValue: string, + public readonly replaceValue: string, + ) { + super(); + } + + public getSerializableProperties(): (keyof this & string)[] { + return ['type', 'searchValue', 'replaceValue']; + } + + public getTextProperties(): (keyof this & string)[] { + return ['searchValue', 'replaceValue']; + } + + public static getAllowedTypes(): ReplaceOperationType[] { + return [ReplaceOperationType.all, ReplaceOperationType.once]; + } +} diff --git a/packages/next/src/config/plugins/ModifySourcePlugin/operations/index.ts b/packages/next/src/config/plugins/ModifySourcePlugin/operations/index.ts new file mode 100644 index 000000000..d5848b6d5 --- /dev/null +++ b/packages/next/src/config/plugins/ModifySourcePlugin/operations/index.ts @@ -0,0 +1,4 @@ +export * from './AbstractOperation'; +export * from './ConcatOperation'; +export * from './ReplaceOperation'; +export * from './Operation'; diff --git a/packages/next/src/config/withHeadlessConfig.ts b/packages/next/src/config/withHeadlessConfig.ts index 0b08d7a5a..44a84a667 100644 --- a/packages/next/src/config/withHeadlessConfig.ts +++ b/packages/next/src/config/withHeadlessConfig.ts @@ -1,8 +1,8 @@ import { ConfigError, HeadlessConfig } from '@headstartwp/core'; import { NextConfig } from 'next'; -import { ModifySourcePlugin, ConcatOperation } from 'modify-source-webpack-plugin'; import path from 'path'; import fs from 'fs'; +import { ModifySourcePlugin, ConcatOperation } from './plugins/ModifySourcePlugin'; const LINARIA_EXTENSION = '.linaria.module.css'; @@ -153,9 +153,17 @@ export function withHeadlessConfig( }, webpack: (config, options) => { + const headlessConfigPath = `${process.cwd()}/headless.config.js`; + const headstartWpConfigPath = `${process.cwd()}/headstartwp.config.js`; + + const configPath = fs.existsSync(headstartWpConfigPath) + ? headstartWpConfigPath + : headlessConfigPath; + const importSetHeadlessConfig = ` - import { setHeadstartWPConfig } from '@headstartwp/core/utils'; - setHeadstartWPConfig(${JSON.stringify(headlessConfig)}); + import { setHeadstartWPConfig as __setHeadstartWPConfig } from '@headstartwp/core/utils'; + import __headlessConfig from '${configPath}'; + __setHeadstartWPConfig(__headlessConfig); `; // clear webpack cache whenever headless.config.js changes or one of the env files diff --git a/packages/next/src/data/server/fetchHookData.ts b/packages/next/src/data/server/fetchHookData.ts index b122fb3cd..a89db56e4 100644 --- a/packages/next/src/data/server/fetchHookData.ts +++ b/packages/next/src/data/server/fetchHookData.ts @@ -158,7 +158,7 @@ export async function fetchHookData { @@ -50,6 +51,9 @@ describe('previewHandler', () => { expect(res.setPreviewData).toHaveBeenCalled(); expect(res._getStatusCode()).toBe(302); + expect(res._getRedirectUrl()).toBe( + '/modi-qui-dignissimos-sed-assumenda-sint-iusto-preview=true', + ); }); it('sets preview cookie path', async () => { @@ -71,6 +75,115 @@ describe('previewHandler', () => { { maxAge: 300, path: '/modi-qui-dignissimos-sed-assumenda-sint-iusto-preview=true' }, ); expect(res._getStatusCode()).toBe(302); + expect(res._getRedirectUrl()).toBe( + '/modi-qui-dignissimos-sed-assumenda-sint-iusto-preview=true', + ); + }); + + it('preview works for custom post types', async () => { + setHeadstartWPConfig({ + customPostTypes: [ + { + slug: 'book', + // reuse existing posts endpoint + endpoint: '/wp-json/wp/v2/posts', + // these should match your file-system routing + single: '/book', + archive: '/books', + }, + ], + }); + + const { req, res } = createMocks({ + method: 'GET', + query: { + post_id: DRAFT_POST_ID, + token: VALID_AUTH_TOKEN, + post_type: 'book', + }, + }); + + res.setPreviewData = jest.fn(); + await previewHandler(req, res); + + expect(res.setPreviewData).toHaveBeenCalledWith( + { + authToken: 'this is a valid auth', + id: 57, + postType: 'book', + revision: false, + }, + { + maxAge: 300, + path: '/book/modi-qui-dignissimos-sed-assumenda-sint-iusto-preview=true', + }, + ); + expect(res._getStatusCode()).toBe(302); + expect(res._getRedirectUrl()).toBe( + '/book/modi-qui-dignissimos-sed-assumenda-sint-iusto-preview=true', + ); + + const { req: reqWithLocale, res: resWithLocale } = createMocks({ + method: 'GET', + query: { + post_id: DRAFT_POST_ID, + token: VALID_AUTH_TOKEN, + post_type: 'book', + locale: 'es', + }, + }); + + resWithLocale.setPreviewData = jest.fn(); + await previewHandler(reqWithLocale, resWithLocale); + + expect(resWithLocale.setPreviewData).toHaveBeenCalledWith( + { + authToken: 'this is a valid auth', + id: 57, + postType: 'book', + revision: false, + }, + { + maxAge: 300, + path: '/es/book/modi-qui-dignissimos-sed-assumenda-sint-iusto-preview=true', + }, + ); + expect(resWithLocale._getStatusCode()).toBe(302); + expect(resWithLocale._getRedirectUrl()).toBe( + '/es/book/modi-qui-dignissimos-sed-assumenda-sint-iusto-preview=true', + ); + }); + + it('sets preview cookie path with locale', async () => { + const { req, res } = createMocks({ + method: 'GET', + query: { + post_id: DRAFT_POST_ID, + token: VALID_AUTH_TOKEN, + post_type: 'post', + locale: 'es', + }, + }); + + res.setPreviewData = jest.fn(); + await previewHandler(req, res); + + expect(res.setPreviewData).toHaveBeenCalledWith( + { + authToken: 'this is a valid auth', + id: 57, + postType: 'post', + revision: false, + }, + { + maxAge: 300, + path: '/es/modi-qui-dignissimos-sed-assumenda-sint-iusto-preview=true', + }, + ); + expect(res._getStatusCode()).toBe(302); + expect(res._getRedirectUrl()).toBe( + '/es/modi-qui-dignissimos-sed-assumenda-sint-iusto-preview=true', + ); }); it('set preview cookie path to all paths if onRedirect is passed without getRedirectPath', async () => { @@ -82,7 +195,7 @@ describe('previewHandler', () => { res.setPreviewData = jest.fn(); await previewHandler(req, res, { onRedirect(req, res) { - return res.redirect('/'); + return res.redirect('/custom-redirect'); }, }); @@ -96,6 +209,7 @@ describe('previewHandler', () => { { maxAge: 300, path: '/' }, ); expect(res._getStatusCode()).toBe(302); + expect(res._getRedirectUrl()).toBe('/custom-redirect'); }); it('set preview cookie path redirectPath if getRedirectPath is passed', async () => { @@ -109,9 +223,6 @@ describe('previewHandler', () => { getRedirectPath() { return '/custom-redirect-path/'; }, - onRedirect(req, res) { - return res.redirect('/'); - }, }); expect(res.setPreviewData).toHaveBeenCalledWith( @@ -124,5 +235,53 @@ describe('previewHandler', () => { { maxAge: 300, path: '/custom-redirect-path-preview=true' }, ); expect(res._getStatusCode()).toBe(302); + expect(res._getRedirectUrl()).toBe('/custom-redirect-path-preview=true'); + }); + + it('correctly takes into account `options`', async () => { + const { req, res } = createMocks({ + method: 'GET', + query: { post_id: DRAFT_POST_ID, token: VALID_AUTH_TOKEN, post_type: 'post' }, + }); + + res.setPreviewData = jest.fn(); + await previewHandler(req, res, { + preparePreviewData(req, res, post, previewData) { + return { ...previewData, myCustomData: true }; + }, + getRedirectPath(defaultRedirectPath) { + // if user already added the suffix we need to make sure it is not added again + return `${defaultRedirectPath}-preview=true`; + }, + }); + + expect(res.setPreviewData).toHaveBeenCalledWith( + { + authToken: 'this is a valid auth', + id: 57, + postType: 'post', + revision: false, + myCustomData: true, + }, + { maxAge: 300, path: '/modi-qui-dignissimos-sed-assumenda-sint-iusto-preview=true' }, + ); + expect(res._getRedirectUrl()).toBe( + '/modi-qui-dignissimos-sed-assumenda-sint-iusto-preview=true', + ); + }); + + it('fails if post type is not defined', async () => { + const { req, res } = createMocks({ + method: 'GET', + query: { post_id: DRAFT_POST_ID, token: VALID_AUTH_TOKEN, post_type: 'recipe' }, + }); + + res.setPreviewData = jest.fn(); + await previewHandler(req, res); + + expect(res._getStatusCode()).toBe(401); + expect(res._getData()).toBe( + 'Cannot preview an unknown post type, did you forget to add it to headless.config.js?', + ); }); }); diff --git a/packages/next/src/handlers/previewHandler.ts b/packages/next/src/handlers/previewHandler.ts index 242b2806c..c9a02cfe7 100644 --- a/packages/next/src/handlers/previewHandler.ts +++ b/packages/next/src/handlers/previewHandler.ts @@ -1,3 +1,4 @@ +/* eslint-disable consistent-return */ import { CustomPostType, getSiteByHost, PostEntity } from '@headstartwp/core'; import { getCustomPostType, getHeadlessConfig } from '@headstartwp/core/utils'; import type { NextApiRequest, NextApiResponse } from 'next'; @@ -44,7 +45,7 @@ export type PreviewHandlerOptions = { previewData: PreviewData, defaultRedirect?: PreviewHandlerOptions['onRedirect'], redirectpath?: string, - ) => NextApiResponse; + ) => void; /** * If passed will override the default redirect path @@ -120,7 +121,7 @@ export async function previewHandler( req: NextApiRequest, res: NextApiResponse, options: PreviewHandlerOptions = {}, -) { +): Promise { const { post_id, post_type, is_revision, token, locale } = req.query; if (req.method !== 'GET') { @@ -142,6 +143,15 @@ export async function previewHandler( const revision = is_revision === '1'; try { + const postTypeDef = getCustomPostType(post_type as string, sourceUrl); + + if (!postTypeDef) { + res.status(401).end( + 'Cannot preview an unknown post type, did you forget to add it to headless.config.js?', + ); + return; + } + const { data } = await fetchHookData( usePost.fetcher(sourceUrl), { @@ -179,12 +189,6 @@ export async function previewHandler( previewData = options.preparePreviewData(req, res, result, previewData); } - const postTypeDef = getCustomPostType(post_type as string, sourceUrl); - - if (!postTypeDef) { - return res.end('Cannot preview an unknown post type'); - } - /** * Builds the default redirect path * @@ -192,14 +196,11 @@ export async function previewHandler( */ const getDefaultRedirectPath = () => { const singleRoute = postTypeDef.single || '/'; - const prefixRoute = singleRoute === '/' ? '' : singleRoute; + // remove leading slashes + const prefixRoute = singleRoute.replace(/^\/+/, ''); const slugOrId = revision ? post_id : slug || post_id; - - if (locale) { - return `/${locale}/${prefixRoute}/${slugOrId}`; - } - - return `${prefixRoute}/${slugOrId}`; + const path = [locale, prefixRoute, slugOrId].filter((n) => n).join('/'); + return `/${path}`; }; const redirectPath = @@ -223,7 +224,7 @@ export async function previewHandler( }); const defaultRedirect: PreviewHandlerOptions['onRedirect'] = (req, res) => { - return res.redirect(redirectPath); + res.redirect(redirectPath); }; if (options?.onRedirect) { @@ -234,9 +235,9 @@ export async function previewHandler( } } catch (e) { if (e instanceof Error) { - return res.status(401).end(e.message); + res.status(401).end(e.message); } } - return res.status(401).end('Unable to set preview mode'); + res.status(401).end('There was an error setting up preview'); } diff --git a/projects/wp-multisite-i18n-nextjs/package.json b/projects/wp-multisite-i18n-nextjs/package.json index ad98cd67a..1455287f8 100644 --- a/projects/wp-multisite-i18n-nextjs/package.json +++ b/projects/wp-multisite-i18n-nextjs/package.json @@ -14,8 +14,8 @@ "lint": "eslint ." }, "dependencies": { - "@headstartwp/core": "^1.1.0-next.5", - "@headstartwp/next": "^1.1.0-next.3", + "@headstartwp/core": "^1.1.2", + "@headstartwp/next": "^1.1.6", "@linaria/babel-preset": "^4.4.5", "@linaria/core": "^4.2.10", "@linaria/react": "^4.3.8", @@ -35,7 +35,7 @@ }, "engineStrict": true, "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" + "node": ">=18.0.0", + "npm": ">=9.0.0" } } diff --git a/projects/wp-multisite-nextjs/package.json b/projects/wp-multisite-nextjs/package.json index 992ea7d8c..a7df9ac37 100644 --- a/projects/wp-multisite-nextjs/package.json +++ b/projects/wp-multisite-nextjs/package.json @@ -14,8 +14,8 @@ "lint": "eslint ." }, "dependencies": { - "@headstartwp/core": "^1.1.0-next.5", - "@headstartwp/next": "^1.1.0-next.3", + "@headstartwp/core": "^1.1.2", + "@headstartwp/next": "^1.1.6", "@linaria/babel-preset": "^4.4.5", "@linaria/core": "^4.2.10", "@linaria/react": "^4.3.8", @@ -35,7 +35,7 @@ }, "engineStrict": true, "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" + "node": ">=18.0.0", + "npm": ">=9.0.0" } } diff --git a/projects/wp-nextjs-ts/package.json b/projects/wp-nextjs-ts/package.json index b13a9fd29..624c17d3f 100644 --- a/projects/wp-nextjs-ts/package.json +++ b/projects/wp-nextjs-ts/package.json @@ -14,8 +14,8 @@ "lint": "eslint ." }, "dependencies": { - "@headstartwp/core": "^1.1.0-next.5", - "@headstartwp/next": "^1.1.0-next.3", + "@headstartwp/core": "^1.1.2", + "@headstartwp/next": "^1.1.6", "@linaria/babel-preset": "^4.4.5", "@linaria/core": "^4.2.10", "@linaria/react": "^4.3.8", @@ -35,7 +35,7 @@ }, "engineStrict": true, "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" + "node": ">=18.0.0", + "npm": ">=9.0.0" } } diff --git a/projects/wp-nextjs/.nvmrc b/projects/wp-nextjs/.nvmrc index 19c7bdba7..25bf17fc5 100644 --- a/projects/wp-nextjs/.nvmrc +++ b/projects/wp-nextjs/.nvmrc @@ -1 +1 @@ -16 \ No newline at end of file +18 \ No newline at end of file diff --git a/projects/wp-nextjs/package.json b/projects/wp-nextjs/package.json index 1e83a070e..2ee303033 100644 --- a/projects/wp-nextjs/package.json +++ b/projects/wp-nextjs/package.json @@ -14,8 +14,8 @@ "lint": "eslint ." }, "dependencies": { - "@headstartwp/core": "^1.1.0-next.5", - "@headstartwp/next": "^1.1.0-next.3", + "@headstartwp/core": "^1.1.2", + "@headstartwp/next": "^1.1.6", "@10up/next-redis-cache-provider": "^0.1.5", "@linaria/babel-preset": "^4.4.5", "@linaria/core": "^4.2.10", @@ -36,7 +36,7 @@ }, "engineStrict": true, "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" + "node": ">=18.0.0", + "npm": ">=9.0.0" } } diff --git a/wp/headless-wp/CHANGELOG.md b/wp/headless-wp/CHANGELOG.md index 73ae8e38f..8893da8e1 100644 --- a/wp/headless-wp/CHANGELOG.md +++ b/wp/headless-wp/CHANGELOG.md @@ -1,5 +1,21 @@ # @headstartwp/headstartwp +## 1.0.10 + +### Patch Changes + +- b54c688e: Fix PHP 8.2 deprecation warnings + +## 1.0.9 + +### Patch Changes + +- 569662b6: Improves the Next.js preview cookie handling and fixes a bug where the locale was not properly being passed from WP when previewing. + + First of all, it sets the preview cookie to expire within 5 minutes which aligns with the JWT token expiration. + + Secondly, it will narrow the cookie to the post path being previewed so that `context.preview` is not true for other paths and thus avoiding bypassing getStaticProps until the cookies are cleared (either expires or the browser closes). + ## 1.0.9-next.0 ### Patch Changes diff --git a/wp/headless-wp/includes/classes/API.php b/wp/headless-wp/includes/classes/API.php index 6ab8cfb21..a2ad7dea4 100644 --- a/wp/headless-wp/includes/classes/API.php +++ b/wp/headless-wp/includes/classes/API.php @@ -98,7 +98,7 @@ public function modify_rest_params( $args, $request ) { return $args; } - $author = filter_input( INPUT_GET, 'author', FILTER_SANITIZE_STRING ); + $author = htmlspecialchars( filter_input( INPUT_GET, 'author' ) ); if ( ! empty( $author ) && ! is_numeric( $author ) ) { unset( $args['author__in'] ); @@ -108,10 +108,10 @@ public function modify_rest_params( $args, $request ) { $taxonomies = wp_list_filter( get_object_taxonomies( $args['post_type'], 'objects' ), [ 'show_in_rest' => true ] ); foreach ( $taxonomies as $taxonomy ) { - $term = filter_input( INPUT_GET, $taxonomy->name, FILTER_SANITIZE_STRING ); + $term = htmlspecialchars( filter_input( INPUT_GET, $taxonomy->name ) ); if ( ! $term ) { - $term = filter_input( INPUT_GET, $taxonomy->rest_base, FILTER_SANITIZE_STRING ); + $term = htmlspecialchars( filter_input( INPUT_GET, $taxonomy->rest_base ) ); } if ( ! empty( $term ) && ! is_numeric( $term ) ) { diff --git a/wp/headless-wp/includes/classes/Integrations/Gutenberg.php b/wp/headless-wp/includes/classes/Integrations/Gutenberg.php index 564d79c18..f70710e28 100644 --- a/wp/headless-wp/includes/classes/Integrations/Gutenberg.php +++ b/wp/headless-wp/includes/classes/Integrations/Gutenberg.php @@ -21,7 +21,6 @@ public function register() { add_filter( 'render_block', [ $this, 'render_block' ], 10, 3 ); } - /** * Process the block with the WP_HTML_Tag_Processor * @@ -75,7 +74,7 @@ public function process_block_with_dom_document_api( $html, $block_name, $block_ try { libxml_use_internal_errors( true ); $doc = new DomDocument( '1.0', 'UTF-8' ); - $doc->loadHTML( mb_convert_encoding( $html, 'HTML-ENTITIES', 'UTF-8' ), LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED ); + $doc->loadHTML( htmlspecialchars_decode( htmlentities( $html ) ), LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED ); $root_node = $doc->documentElement; // phpcs:ignore diff --git a/wp/headless-wp/package.json b/wp/headless-wp/package.json index 206298aa1..f30ab277b 100644 --- a/wp/headless-wp/package.json +++ b/wp/headless-wp/package.json @@ -1,6 +1,6 @@ { "name": "@headstartwp/headstartwp", - "version": "1.0.9-next.0", + "version": "1.0.10", "private": true, "description": "10up Headless WordPress Plugin", "homepage": "https://github.com/10up/headstartwp/blob/develop/wp/headless-wp/README.md", diff --git a/wp/headless-wp/plugin.php b/wp/headless-wp/plugin.php index 7ee678902..fa67b7544 100644 --- a/wp/headless-wp/plugin.php +++ b/wp/headless-wp/plugin.php @@ -3,7 +3,7 @@ * Plugin Name: HeadstartWP * Plugin URI: https://github.com/10up/headstartwp-plugin * Description: Adds functionality to the WordPress admin and REST API for 10up's headless framework. - * Version: 1.0.9-next.0 + * Version: 1.0.10 * Author: 10up * Author URI: https://10up.com * Text Domain: headstartwp @@ -17,7 +17,7 @@ use HeadlessWP\Preview\PreviewToken; // Useful global constants. -define( 'HEADLESS_WP_PLUGIN_VERSION', '1.0.9-next.0' ); +define( 'HEADLESS_WP_PLUGIN_VERSION', '1.0.10' ); define( 'HEADLESS_WP_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); define( 'HEADLESS_WP_PLUGIN_PATH', plugin_dir_path( __FILE__ ) ); define( 'HEADLESS_WP_PLUGIN_INC', HEADLESS_WP_PLUGIN_PATH . 'includes/' );