diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000000..1fe1d8f46901a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,328 @@ +# Configure Dependabot scanning. +version: 2 + +updates: + # Check for updates to GitHub Actions. + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + open-pull-requests-limit: 50 + cooldown: + default-days: 7 + groups: + github-actions: + applies-to: version-updates + update-types: + - minor + - patch + + # Check for updates to Composer packages. + - package-ecosystem: "composer" + directory: "/" + schedule: + interval: "daily" + open-pull-requests-limit: 50 + cooldown: + default-days: 7 + ignore: + # These dependencies do not currently need to be managed with Dependabot. + - dependency-name: "squizlabs/php_codesniffer" + - dependency-name: "wp-coding-standards/wpcs" + - dependency-name: "phpcompatibility/php-compatibility" + - dependency-name: "yoast/phpunit-polyfills" + groups: + composer-packages: + patterns: + - "composer/ca-bundle" + + # Monitor some npm dependencies for updates in groups. + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "daily" + open-pull-requests-limit: 50 + cooldown: + default-days: 7 + ignore: + - dependency-name: "@wordpress/*" + groups: + ## + # Groups for updating devDependencies. + ## + + # Dependencies related to Playwright testing (E2E, performance). + tests-playwright: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "*playwright*" + # Dependencies related to JavaScript testing with QUnit. + tests-qunit: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "*qunit*" + - "sinon*" + # Dependencies related to CSS and SASS building and manilupating. + dev-css-sass: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "autoprefixer" + # postcss and css related dependencies. + - "*css*" + - "*sass" + # Dependencies related to the Webpack build process. + dev-webpack: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "*webpack*" + - "react-refresh" + - "source-map-loader" + # Dependencies related to the local Docker development environment. + dev-docker: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "dotenv*" + - "wait-on" + # Dependencies that do not fall into a specific grouping. + dev-miscellaneous: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "chalk" + - "check-node-version" + - "ink-docstrap" + - "install-changed" + - "matchdep" + - "uuid" + # Dependencies related to JavaScript minification. + dev-uglify: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "*uglify*" + # All GruntJS related dependencies that do not relate to another group. + dev-grunt: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "*grunt*" + + ## + # Groups for updating production dependencies. + ## + + # Dependencies related to jQuery and its ecosystem. + external-jquery: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "jquery*" + # Dependencies related to React and its ecosystem. + external-react: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "react*" + - "!react-refresh" + # Dependencies used for bundling polyfill libraries into WordPress. + external-polyfills: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "core-js-url-browser" + - "element-closest" + - "formdata-polyfill" + - "imagesloaded" + - "objectFitPolyfill" + - "polyfill-library" + - "regenerator-runtime" + - "whatwg-fetch" + - "wicg-inert" + # Dependencies related to the Masonry library. + external-masonry: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "masonry-layout" + # Dependencies that do not fall into a specific grouping. + external-miscellaneous: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "backbone" + - "clipboard" + - "hoverintent" + - "json2php" + - "lodash" + - "moment" + - "underscore" + + # Monitor npm dependencies within default themes. + - package-ecosystem: "npm" + directory: "/src/wp-content/themes/twentytwentyfive" + schedule: + interval: "weekly" + open-pull-requests-limit: 50 + cooldown: + default-days: 7 + groups: + twentytwentyfive-css: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "**browserslist*" + - "*css*" + + - package-ecosystem: "npm" + directory: "/src/wp-content/themes/twentytwentytwo" + schedule: + interval: "weekly" + open-pull-requests-limit: 50 + cooldown: + default-days: 7 + groups: + twentytwentytwo-css: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "**browserslist*" + - "*css*" + + - package-ecosystem: "npm" + directory: "/src/wp-content/themes/twentytwentyone" + schedule: + interval: "weekly" + open-pull-requests-limit: 50 + cooldown: + default-days: 7 + groups: + twentytwentyone-sass-css: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "**browserslist*" + - "autoprefixer" + - "*css*" + - "*sass*" + - "!*stylelint*" + twentytwentyone-eslint: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "**eslint*" + twentytwentyone-stylelint: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "**stylelint*" + twentytwentyone-miscellaneous: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "chokidar-cli" + - "minimist" + - "npm-run-all" + + - package-ecosystem: "npm" + directory: "/src/wp-content/themes/twentytwenty" + schedule: + interval: "weekly" + open-pull-requests-limit: 50 + cooldown: + default-days: 7 + groups: + twentytwenty-css: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "**browserslist*" + - "autoprefixer" + - "*css*" + twentytwenty-stylelint: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "*stylelint*" + twentytwenty-miscellaneous: + applies-to: version-updates + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "concurrently" + - "@wordpress/scripts" + + - package-ecosystem: "npm" + directory: "/src/wp-content/themes/twentynineteen" + schedule: + interval: "weekly" + open-pull-requests-limit: 50 + cooldown: + default-days: 7 + groups: + twentynineteen-css-sass: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "**browserslist*" + - "autoprefixer" + - "*css*" + - "*sass*" + twentynineteen-miscellaneous: + applies-to: version-updates + update-types: + - minor + - patch + patterns: + - "chokidar-cli" + - "npm-run-all" diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml new file mode 100644 index 0000000000000..a6091199be590 --- /dev/null +++ b/.github/workflows/backport.yml @@ -0,0 +1,369 @@ +name: Create backport pull requests + +on: + workflow_dispatch: + inputs: + end_branch: + description: 'The branch to end at (e.g. 6.9). Defaults to the current supported branch.' + required: false + type: string + default: '7.0' + pr-name: + description: 'Pull request name (format is " - branch".' + required: false + type: string + default: '' + commit-sha: + description: 'Full length commit hash to stage for backport.' + required: false + type: string + default: '' + pr_numbers: + description: 'Comma-separated PR numbers. Ignored when a SHA is provided.' + required: false + type: string + default: '' + repo-source: + description: 'Repository to merge changes from.' + required: false + type: choice + default: 'upstream' + options: + - upstream + - current + pr-target: + description: 'Repository to submit pull requests to.' + required: false + type: choice + default: 'current' + options: + - upstream + - current + +# Disable permissions for all available scopes by default. +# Any needed permissions should be configured at the job level. +permissions: {} + +jobs: + validate-inputs: + name: Validate inputs + runs-on: ubuntu-24.04 + steps: + - name: Ensure a commit SHA or PR numbers are provided + env: + INPUTS_COMMIT_SHA: ${{ inputs.commit-sha }} + INPUTS_PR_NUMBERS: ${{ inputs.pr_numbers }} + run: | + if [ -z "${INPUTS_COMMIT_SHA}" ] && [ -z "${INPUTS_PR_NUMBERS}" ]; then + echo "::error::A commit SHA or PR number(s) must be included." + exit 1 + fi + + get-branches: + name: Get target branches + needs: [ 'validate-inputs' ] + runs-on: ubuntu-24.04 + outputs: + branches: ${{ steps.branches.outputs.result }} + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + # Read keys from .version-support-php.json, filter to those >= end_branch, + # convert dashes to dots, and sort numerically descending. + # The first key is always the version in active development on trunk, so skip it. + - name: Get target branches + id: branches + env: + INPUTS_END_BRANCH: ${{ inputs.end_branch }} + run: | + END_X=$(echo "${INPUTS_END_BRANCH}" | cut -d. -f1) + END_Y=$(echo "${INPUTS_END_BRANCH}" | cut -d. -f2) + + BRANCHES=$(jq -c \ + --argjson x "$END_X" \ + --argjson y "$END_Y" \ + '[ keys[] | + . as $k | ($k | split("-")) as $p | + select( ($p[0]|tonumber) > $x or + (($p[0]|tonumber) == $x and ($p[1]|tonumber) >= $y) ) | + { v: ($k | gsub("-"; ".")), x: ($p[0]|tonumber), y: ($p[1]|tonumber) } + ] | sort_by(.x, .y) | reverse | .[1:] | map(.v)' \ + .version-support-php.json) + + echo "result=$BRANCHES" >> "$GITHUB_OUTPUT" + + backport: + name: 'Backport to ${{ matrix.branch }}' + needs: [ 'validate-inputs', 'get-branches' ] + if: ${{ needs.get-branches.outputs.branches != '[]' }} + runs-on: ubuntu-24.04 + permissions: + contents: write + pull-requests: write + strategy: + fail-fast: false + matrix: + branch: ${{ fromJson( needs.get-branches.outputs.branches ) }} + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + persist-credentials: 'true' + + - name: Set up git identity + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + - name: Add upstream remote + id: upstream + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + UPSTREAM=$(gh repo view "${{ github.repository }}" --json parent --jq 'if .parent then "\(.parent.owner.login)/\(.parent.name)" else empty end') + if [ -n "$UPSTREAM" ]; then + git remote add upstream "https://github.com/${UPSTREAM}.git" + git fetch upstream + echo "repo=$UPSTREAM" >> "$GITHUB_OUTPUT" + else + echo "repo=${{ github.repository }}" >> "$GITHUB_OUTPUT" + fi + + # Determine the name of the branch for the pull request. + # + # 1. pr-name (normalized to alphanumeric, hyphens, and periods only) + # 2. commit-sha + # 3. pr_numbers with commas replaced by hyphens + - name: Determine backport branch name + id: backport-branch + env: + INPUTS_PR_NAME: ${{ inputs.pr-name }} + MATRIX_BRANCH: ${{ matrix.branch }} + INPUTS_COMMIT_SHA: ${{ inputs.commit-sha }} + INPUTS_PR_NUMBERS: ${{ inputs.pr_numbers }} + run: | + if [ -n "${INPUTS_PR_NAME}" ]; then + echo "name=backport/${MATRIX_BRANCH}-$(echo "${INPUTS_PR_NAME}" | tr -cs '[:alnum:].-' '-' | sed 's/^-//;s/-$//')" >> "$GITHUB_OUTPUT" + elif [ -n "${INPUTS_COMMIT_SHA}" ]; then + echo "name=backport/${MATRIX_BRANCH}-${INPUTS_COMMIT_SHA}" >> "$GITHUB_OUTPUT" + else + echo "name=backport/${MATRIX_BRANCH}-$(echo "${INPUTS_PR_NUMBERS}" | tr -d ' ' | tr ',' '-')" >> "$GITHUB_OUTPUT" + fi + + - name: Create backport branch + env: + STEPS_BACKPORT_BRANCH_OUTPUTS_NAME: ${{ steps.backport-branch.outputs.name }} + MATRIX_BRANCH: ${{ matrix.branch }} + run: | + if git ls-remote --exit-code --heads origin "${STEPS_BACKPORT_BRANCH_OUTPUTS_NAME}" > /dev/null 2>&1; then + echo "::error::Branch '${STEPS_BACKPORT_BRANCH_OUTPUTS_NAME}' already exists on origin." + exit 1 + fi + + git checkout -b "${STEPS_BACKPORT_BRANCH_OUTPUTS_NAME}" "origin/${MATRIX_BRANCH}" + + - name: Cherry-pick commit + if: ${{ inputs['commit-sha'] != '' }} + env: + INPUTS_COMMIT_SHA: ${{ inputs.commit-sha }} + run: | + COMMIT="${INPUTS_COMMIT_SHA}" + PARENTS=$(git cat-file -p "$COMMIT" | grep -c '^parent ' || true) + + if [ "$PARENTS" -gt 1 ]; then + git cherry-pick -m 1 "$COMMIT" + else + git cherry-pick "$COMMIT" + fi + + - name: Merge PRs + id: merge-prs + if: ${{ inputs['commit-sha'] == '' && inputs.pr_numbers != '' }} + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + STEPS_UPSTREAM_OUTPUTS_REPO: ${{ steps.upstream.outputs.repo }} + INPUTS_PR_NUMBERS: ${{ inputs.pr_numbers }} + INPUTS_REPO_SOURCE: ${{ inputs.repo-source }} + run: | + if [ "${INPUTS_REPO_SOURCE}" = "upstream" ]; then + PR_REPO="${STEPS_UPSTREAM_OUTPUTS_REPO}" + else + PR_REPO="${GITHUB_REPOSITORY}" + fi + + IFS=',' read -ra PR_LIST <<< "${INPUTS_PR_NUMBERS}" + + UPSTREAM_URL="https://github.com/${STEPS_UPSTREAM_OUTPUTS_REPO}.git" + RESULTS="" + FAILED=false + + for PR_NUMBER in "${PR_LIST[@]}"; do + PR_NUMBER=$(echo "$PR_NUMBER" | tr -d ' ') + + PR_DATA=$(gh pr view "$PR_NUMBER" --repo "$PR_REPO" --json title,mergeCommit,baseRefName) + PR_TITLE=$(echo "$PR_DATA" | jq -r '.title') + MERGE_COMMIT=$(echo "$PR_DATA" | jq -r '.mergeCommit.oid') + + set +e + if [ -n "$MERGE_COMMIT" ] && [ "$MERGE_COMMIT" != "null" ]; then + # PR is merged: cherry-pick its merge commit. + # Determine if it is a merge commit or squash commit. + PARENTS=$(git cat-file -p "$MERGE_COMMIT" | grep -c '^parent ' || true) + + if [ "$PARENTS" -gt 1 ]; then + git cherry-pick -m 1 --no-commit "$MERGE_COMMIT" + else + git cherry-pick --no-commit "$MERGE_COMMIT" + fi + else + # PR is open or closed without merging: apply its changes as a diff + # against the point where it diverged from its base branch. + BASE_REF=$(echo "$PR_DATA" | jq -r '.baseRefName') + + git fetch "$UPSTREAM_URL" "$BASE_REF" + BASE_SHA=$(git rev-parse FETCH_HEAD) + + git fetch "$UPSTREAM_URL" "refs/pull/${PR_NUMBER}/head" + PR_HEAD_SHA=$(git rev-parse FETCH_HEAD) + + MERGE_BASE=$(git merge-base "$PR_HEAD_SHA" "$BASE_SHA") + git diff "$MERGE_BASE" "$PR_HEAD_SHA" | git apply --index + fi + APPLY_EXIT=$? + set -e + + if [ $APPLY_EXIT -eq 0 ]; then + git commit -m "$PR_TITLE" + RESULTS="${RESULTS}${PR_NUMBER}=✅ " + else + git cherry-pick --abort 2>/dev/null || git reset --hard HEAD + RESULTS="${RESULTS}${PR_NUMBER}=❌ " + FAILED=true + break + fi + done + + echo "results=${RESULTS}" >> "$GITHUB_OUTPUT" + + if [ "$FAILED" = "true" ]; then + exit 1 + fi + + - name: Push backport branch + env: + STEPS_BACKPORT_BRANCH_OUTPUTS_NAME: ${{ steps.backport-branch.outputs.name }} + run: git push -u origin "${STEPS_BACKPORT_BRANCH_OUTPUTS_NAME}" + + - name: Create pull request + id: create-pr + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + STEPS_UPSTREAM_OUTPUTS_REPO: ${{ steps.upstream.outputs.repo }} + INPUTS_PR_NAME: ${{ inputs.pr-name }} + MATRIX_BRANCH: ${{ matrix.branch }} + INPUTS_COMMIT_SHA: ${{ inputs.commit-sha }} + INPUTS_PR_NUMBERS: ${{ inputs.pr_numbers }} + INPUTS_REPO_SOURCE: ${{ inputs.repo-source }} + INPUTS_PR_TARGET: ${{ inputs.pr-target }} + STEPS_BACKPORT_BRANCH_OUTPUTS_NAME: ${{ steps.backport-branch.outputs.name }} + run: | + if [ "${INPUTS_REPO_SOURCE}" = "upstream" ]; then + PR_REPO="${STEPS_UPSTREAM_OUTPUTS_REPO}" + else + PR_REPO="${GITHUB_REPOSITORY}" + fi + + if [ -n "${INPUTS_PR_NAME}" ]; then + PR_TITLE="${INPUTS_PR_NAME} - ${MATRIX_BRANCH} branch" + else + PR_TITLE="Backport to ${MATRIX_BRANCH}" + fi + + if [ -n "${INPUTS_COMMIT_SHA}" ]; then + BODY="This pull request backports \`${INPUTS_COMMIT_SHA}\` (https://github.com/${STEPS_UPSTREAM_OUTPUTS_REPO}/commit/${INPUTS_COMMIT_SHA}) to the \`${MATRIX_BRANCH}\` branch." + else + BODY="Backports to the \`${MATRIX_BRANCH}\` branch." + fi + + BODY="${BODY}\n\n## Changes Included\n" + + if [ -n "${INPUTS_COMMIT_SHA}" ]; then + COMMIT_MESSAGE=$(git log --format=%B -n 1 "${INPUTS_COMMIT_SHA}") + BLOCKQUOTE=$(echo "${COMMIT_MESSAGE}" | sed 's/^/> /') + BODY="${BODY}\n${BLOCKQUOTE}" + fi + + if [ -n "${INPUTS_PR_NUMBERS}" ] && [ -z "${INPUTS_COMMIT_SHA}" ]; then + IFS=',' read -ra PR_LIST <<< "${INPUTS_PR_NUMBERS}" + for PR_NUMBER in "${PR_LIST[@]}"; do + PR_NUMBER=$(echo "$PR_NUMBER" | tr -d ' ') + BODY="${BODY}\n- ${PR_REPO}#${PR_NUMBER}" + done + fi + + if [ "${INPUTS_PR_TARGET}" = "upstream" ]; then + PR_REPO="${STEPS_UPSTREAM_OUTPUTS_REPO}" + PR_HEAD="${GITHUB_REPOSITORY_OWNER}:${STEPS_BACKPORT_BRANCH_OUTPUTS_NAME}" + else + PR_REPO="${GITHUB_REPOSITORY}" + PR_HEAD="${STEPS_BACKPORT_BRANCH_OUTPUTS_NAME}" + fi + + PR_URL=$(gh pr create \ + --repo "${PR_REPO}" \ + --base "${MATRIX_BRANCH}" \ + --head "${PR_HEAD}" \ + --title "$PR_TITLE" \ + --assignee "${GITHUB_ACTOR}" \ + --draft \ + --body "$(echo -e "$BODY")") + + if gh label list --repo "${PR_REPO}" --json name --jq '[.[].name] | contains(["Auto-backport"])' | grep -q 'true'; then + gh pr edit "$PR_URL" --repo "${PR_REPO}" --add-label 'Auto-backport' + else + echo "::notice::The 'Auto-backport' label does not exist on ${PR_REPO}. Consider adding it so that backport pull requests can be identified easily." + fi + + echo "url=${PR_URL}" >> "$GITHUB_OUTPUT" + + - name: Write job summary + if: always() + env: + MATRIX_BRANCH: ${{ matrix.branch }} + INPUTS_COMMIT_SHA: ${{ inputs.commit-sha }} + INPUTS_PR_NUMBERS: ${{ inputs.pr_numbers }} + STEPS_MERGE_PRS_OUTPUTS_RESULTS: ${{ steps.merge-prs.outputs.results }} + STEPS_CREATE_PR_OUTPUTS_URL: ${{ steps.create-pr.outputs.url }} + run: | + PR_DISPLAY="${STEPS_CREATE_PR_OUTPUTS_URL:-N/A}" + + if [ -n "${INPUTS_PR_NUMBERS}" ] && [ -z "${INPUTS_COMMIT_SHA}" ]; then + IFS=',' read -ra PR_LIST <<< "${INPUTS_PR_NUMBERS}" + + HEADER="| Branch |" + SEPARATOR="| :--- |" + for PR_NUM in "${PR_LIST[@]}"; do + PR_NUM=$(echo "$PR_NUM" | tr -d ' ') + HEADER="${HEADER} #${PR_NUM} |" + SEPARATOR="${SEPARATOR} :---: |" + done + HEADER="${HEADER} Pull Request |" + SEPARATOR="${SEPARATOR} :--- |" + + ROW="| \`${MATRIX_BRANCH}\` |" + for PR_NUM in "${PR_LIST[@]}"; do + PR_NUM=$(echo "$PR_NUM" | tr -d ' ') + STATUS=$(echo "${STEPS_MERGE_PRS_OUTPUTS_RESULTS}" | tr ' ' '\n' | grep "^${PR_NUM}=" | cut -d= -f2) + ROW="${ROW} ${STATUS:-❌} |" + done + ROW="${ROW} ${PR_DISPLAY} |" + + printf '%s\n%s\n%s\n' "$HEADER" "$SEPARATOR" "$ROW" >> "$GITHUB_STEP_SUMMARY" + else + printf '| Branch | Pull Request |\n| :--- | :--- |\n| `%s` | %s |\n' \ + "${MATRIX_BRANCH}" "${PR_DISPLAY}" >> "$GITHUB_STEP_SUMMARY" + fi diff --git a/.github/workflows/create-backport-prs.yml b/.github/workflows/create-backport-prs.yml new file mode 100644 index 0000000000000..f0ad03ecc9636 --- /dev/null +++ b/.github/workflows/create-backport-prs.yml @@ -0,0 +1,532 @@ +name: Create backport pull requests + +on: + workflow_dispatch: + inputs: + end_branch: + description: 'The branch to end at (e.g. 6.9). Defaults to the current supported branch.' + required: false + type: string + default: '7.0' + pr-name: + description: 'Pull request name (format is " - branch".' + required: false + type: string + default: '' + commit-sha: + description: 'Full length commit hash to stage for backport.' + required: false + type: string + default: '' + pr_numbers: + description: 'Comma-separated PR numbers. Ignored when a SHA is provided.' + required: false + type: string + default: '' + repo-source: + description: 'Repository to merge changes from.' + required: false + type: choice + default: 'upstream' + options: + - upstream + - current + pr-target: + description: 'Repository to submit pull requests to.' + required: false + type: choice + default: 'current' + options: + - upstream + - current + +# Disable permissions for all available scopes by default. +# Any needed permissions should be configured at the job level. +permissions: {} + +jobs: + # Confirms that enough information is included to attempt a backport. + validate-inputs: + name: Validate inputs + runs-on: ubuntu-24.04 + steps: + - name: Ensure a commit SHA or PR numbers are provided + env: + COMMIT_SHA: ${{ inputs.commit-sha }} + PR_NUMBERS: ${{ inputs.pr_numbers }} + run: | + if [ -z "${COMMIT_SHA}" ] && [ -z "${PR_NUMBERS}" ]; then + echo "::error::A commit SHA or PR number(s) must be included." + exit 1 + fi + + # Generates a list of branches to create backport PRs for. + # + # The keys are read from .version-support-php.json, filtered to only include + # any after the specified end branch, and sort numerically descending. + # + # The first key in the file is always skipped because it represents the next + # version of WordPress in active development in trunk. + # + # Performs the following steps: + # - Checks out the repository. + # - Reads branch versions from .version-support-php.json and outputs a filtered, sorted list. + get-branches: + name: Get target branches + needs: [ 'validate-inputs' ] + runs-on: ubuntu-24.04 + outputs: + branches: ${{ steps.branches.outputs.result }} + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Get target branches + id: branches + env: + END_BRANCH: ${{ inputs.end_branch }} + run: | + END_X=$(echo "${END_BRANCH}" | cut -d. -f1) + END_Y=$(echo "${END_BRANCH}" | cut -d. -f2) + + BRANCHES=$(jq -c \ + --argjson x "$END_X" \ + --argjson y "$END_Y" \ + '[ keys[] | + . as $k | ($k | split("-")) as $p | + select( ($p[0]|tonumber) > $x or + (($p[0]|tonumber) == $x and ($p[1]|tonumber) >= $y) ) | + { v: ($k | gsub("-"; ".")), x: ($p[0]|tonumber), y: ($p[1]|tonumber) } + ] | sort_by(.x, .y) | reverse | .[1:] | map(.v)' \ + .version-support-php.json) + + echo "result=$BRANCHES" >> "$GITHUB_OUTPUT" + + # Resolves shared context and variables used by all matrix jobs. + # + # The branch name suffix is determined in the following order: + # 1. pr-name (normalized to alphanumeric, hyphens, and periods only) + # 2. commit-sha + # 3. pr_numbers with commas replaced by hyphens + # + # Performs the following steps: + # - Determines whether the repository is a fork. + # - Constructs the branch name suffix. + resolve-context: + name: Resolve context + needs: [ 'validate-inputs', 'get-branches' ] + if: ${{ needs.get-branches.outputs.branches != '[]' }} + runs-on: ubuntu-24.04 + permissions: + contents: read + outputs: + upstream-repo: ${{ steps.upstream.outputs.repo }} + branch-suffix: ${{ steps.branch-suffix.outputs.value }} + steps: + - name: Detect upstream repository + id: upstream + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + UPSTREAM=$(gh repo view "${{ github.repository }}" --json parent --jq 'if .parent then "\(.parent.owner.login)/\(.parent.name)" else empty end') + if [ -n "$UPSTREAM" ]; then + echo "This repository is a fork of ${UPSTREAM}. Original repository configured as \`upstream\` remote." + echo "repo=$UPSTREAM" >> "$GITHUB_OUTPUT" + else + echo "This repository is not a fork. No \`upstream\` remote configured." + echo "repo=${{ github.repository }}" >> "$GITHUB_OUTPUT" + fi + + - name: Determine branch name suffix + id: branch-suffix + env: + PR_NAME: ${{ inputs.pr-name }} + COMMIT_SHA: ${{ inputs.commit-sha }} + PR_NUMBERS: ${{ inputs.pr_numbers }} + run: | + if [ -n "${PR_NAME}" ]; then + echo "value=$(echo "${PR_NAME}" | tr -cs '[:alnum:].-' '-' | sed 's/^-//;s/-$//')" >> "$GITHUB_OUTPUT" + elif [ -n "${COMMIT_SHA}" ]; then + echo "value=${COMMIT_SHA}" >> "$GITHUB_OUTPUT" + else + echo "value=$(echo "${PR_NUMBERS}" | tr -d ' ' | tr ',' '-')" >> "$GITHUB_OUTPUT" + fi + + # Attempts to backport the specified changes in the desired branches. + # + # Performs the following steps: + # - Checks out the repository. + # - Configures the Git author. + # - Configures the upstream remote (forks only). + # - Creates a new branch. + # - Performs a `git cherry-pick` when a SHA value is specified. + # - Attempts to merge changes from the pull requests specified. + # - Pushes the new branch to the origin remote. + backport: + name: 'Backport to ${{ matrix.branch }}' + needs: [ 'validate-inputs', 'get-branches', 'resolve-context' ] + runs-on: ubuntu-24.04 + permissions: + contents: write + strategy: + fail-fast: false + matrix: + branch: ${{ fromJson( needs.get-branches.outputs.branches ) }} + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + persist-credentials: 'true' + + - name: Configure git user name and email + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + - name: Add upstream remote + env: + UPSTREAM_REPO: ${{ needs.resolve-context.outputs.upstream-repo }} + run: | + if [ "${UPSTREAM_REPO}" != "${{ github.repository }}" ]; then + git remote add upstream "https://github.com/${UPSTREAM_REPO}.git" + git fetch upstream + fi + + - name: Create backport branch + env: + MATRIX_BRANCH: ${{ matrix.branch }} + HEAD_BRANCH_SUFFIX: ${{ needs.resolve-context.outputs.branch-suffix }} + run: | + BRANCH_NAME="backport-${MATRIX_BRANCH}/${HEAD_BRANCH_SUFFIX}" + + if git ls-remote --exit-code --heads origin "${BRANCH_NAME}" > /dev/null 2>&1; then + echo "::error::Branch '${BRANCH_NAME}' already exists on origin." + exit 1 + fi + + git checkout -b "${BRANCH_NAME}" "origin/${MATRIX_BRANCH}" + + - name: Cherry-pick commit + if: ${{ inputs['commit-sha'] != '' }} + env: + COMMIT_SHA: ${{ inputs.commit-sha }} + run: | + COMMIT="${COMMIT_SHA}" + PARENTS=$(git cat-file -p "$COMMIT" | grep -c '^parent ' || true) + + if [ "$PARENTS" -gt 1 ]; then + git cherry-pick -m 1 "$COMMIT" + else + git cherry-pick "$COMMIT" + fi + + - name: Merge PRs + id: merge-prs + if: ${{ inputs['commit-sha'] == '' && inputs.pr_numbers != '' }} + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + UPSTREAM_REPO: ${{ needs.resolve-context.outputs.upstream-repo }} + PR_NUMBERS: ${{ inputs.pr_numbers }} + REPO_SOURCE: ${{ inputs.repo-source }} + run: | + if [ "${REPO_SOURCE}" = "upstream" ]; then + PR_REPO="${UPSTREAM_REPO}" + else + PR_REPO="${GITHUB_REPOSITORY}" + fi + + IFS=',' read -ra PR_LIST <<< "${PR_NUMBERS}" + + UPSTREAM_URL="https://github.com/${UPSTREAM_REPO}.git" + RESULTS="" + FAILED=false + + for PR_NUMBER in "${PR_LIST[@]}"; do + PR_NUMBER=$(echo "$PR_NUMBER" | tr -d ' ') + + PR_DATA=$(gh pr view "$PR_NUMBER" --repo "$PR_REPO" --json title,mergeCommit,baseRefName) + PR_TITLE=$(echo "$PR_DATA" | jq -r '.title') + MERGE_COMMIT=$(echo "$PR_DATA" | jq -r '.mergeCommit.oid') + + set +e + if [ -n "$MERGE_COMMIT" ] && [ "$MERGE_COMMIT" != "null" ]; then + # PR is merged: cherry-pick its merge commit. + # Determine if it is a merge commit or squash commit. + PARENTS=$(git cat-file -p "$MERGE_COMMIT" | grep -c '^parent ' || true) + + if [ "$PARENTS" -gt 1 ]; then + git cherry-pick -m 1 --no-commit "$MERGE_COMMIT" + else + git cherry-pick --no-commit "$MERGE_COMMIT" + fi + else + # PR is open or closed without merging: apply its changes as a diff + # against the point where it diverged from its base branch. + BASE_REF=$(echo "$PR_DATA" | jq -r '.baseRefName') + + git fetch "$UPSTREAM_URL" "$BASE_REF" + BASE_SHA=$(git rev-parse FETCH_HEAD) + + git fetch "$UPSTREAM_URL" "refs/pull/${PR_NUMBER}/head" + PR_HEAD_SHA=$(git rev-parse FETCH_HEAD) + + MERGE_BASE=$(git merge-base "$PR_HEAD_SHA" "$BASE_SHA") + git diff "$MERGE_BASE" "$PR_HEAD_SHA" | git apply --index + fi + APPLY_EXIT=$? + set -e + + if [ $APPLY_EXIT -eq 0 ]; then + git commit -m "$PR_TITLE" + RESULTS="${RESULTS}${PR_NUMBER}=✅ " + else + git cherry-pick --abort 2>/dev/null || git reset --hard HEAD + RESULTS="${RESULTS}${PR_NUMBER}=❌ " + FAILED=true + fi + done + + echo "results=${RESULTS}" >> "$GITHUB_OUTPUT" + + if [ "$FAILED" = "true" ]; then + exit 1 + fi + + - name: Push backport branch + env: + MATRIX_BRANCH: ${{ matrix.branch }} + HEAD_BRANCH_SUFFIX: ${{ needs.resolve-context.outputs.branch-suffix }} + run: git push -u origin "backport-${MATRIX_BRANCH}/${HEAD_BRANCH_SUFFIX}" + + - name: Save results + if: always() + env: + MATRIX_BRANCH: ${{ matrix.branch }} + MERGE_RESULTS: ${{ steps.merge-prs.outputs.results }} + run: | + mkdir -p apply-results + SAFE_BRANCH=$(echo "${MATRIX_BRANCH}" | tr '.' '-') + { + echo "branch=${MATRIX_BRANCH}" + echo "merge_results=${MERGE_RESULTS}" + } > "apply-results/${SAFE_BRANCH}.txt" + + - name: Upload results + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: apply-results-${{ matrix.branch }} + path: apply-results/ + retention-days: 1 + + # Creates a draft pull request for each successfully applied backport branch. + # Requires only write access to pull requests, keeping git operations separate. + # + # Performs the following steps: + # - Downloads the apply result artifact to confirm changes were applied successfully. + # - Creates a draft pull request targeting the specified repository. + # - Adds the `Auto-backport` label to the pull request if it exists. + # - Formats and uploads a pre-rendered summary row artifact for the report job. + create-pr: + name: 'Create PR for ${{ matrix.branch }}' + needs: [ 'validate-inputs', 'get-branches', 'resolve-context', 'backport' ] + if: ${{ always() && !cancelled() && needs.resolve-context.result == 'success' }} + runs-on: ubuntu-24.04 + permissions: + contents: read + pull-requests: write + strategy: + fail-fast: false + matrix: + branch: ${{ fromJson( needs.get-branches.outputs.branches ) }} + steps: + - name: Download apply result + id: apply-result + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: apply-results-${{ matrix.branch }} + path: apply-result/ + continue-on-error: true + + - name: Create pull request + id: create-pr + if: ${{ steps.apply-result.outcome == 'success' }} + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + UPSTREAM_REPO: ${{ needs.resolve-context.outputs.upstream-repo }} + HEAD_BRANCH_SUFFIX: ${{ needs.resolve-context.outputs.branch-suffix }} + PR_NAME: ${{ inputs.pr-name }} + MATRIX_BRANCH: ${{ matrix.branch }} + COMMIT_SHA: ${{ inputs.commit-sha }} + PR_NUMBERS: ${{ inputs.pr_numbers }} + REPO_SOURCE: ${{ inputs.repo-source }} + PR_TARGET: ${{ inputs.pr-target }} + run: | + BACKPORT_BRANCH="backport-${MATRIX_BRANCH}/${HEAD_BRANCH_SUFFIX}" + + if [ "${REPO_SOURCE}" = "upstream" ]; then + SOURCE_REPO="${UPSTREAM_REPO}" + else + SOURCE_REPO="${GITHUB_REPOSITORY}" + fi + + if [ -n "${PR_NAME}" ]; then + PR_TITLE="${PR_NAME} - ${MATRIX_BRANCH} branch" + else + PR_TITLE="Backport to ${MATRIX_BRANCH}" + fi + + if [ -n "${COMMIT_SHA}" ]; then + BODY="This pull request backports \`${COMMIT_SHA}\` (https://github.com/${UPSTREAM_REPO}/commit/${COMMIT_SHA}) to the \`${MATRIX_BRANCH}\` branch." + else + BODY="Backports to the \`${MATRIX_BRANCH}\` branch." + fi + + BODY="${BODY}\n\n## Changes Included\n" + + if [ -n "${COMMIT_SHA}" ]; then + COMMIT_MESSAGE=$(gh api "repos/${UPSTREAM_REPO}/commits/${COMMIT_SHA}" --jq '.commit.message') + BLOCKQUOTE=$(echo "${COMMIT_MESSAGE}" | sed 's/^/> /') + BODY="${BODY}\n${BLOCKQUOTE}" + fi + + if [ -n "${PR_NUMBERS}" ] && [ -z "${COMMIT_SHA}" ]; then + IFS=',' read -ra PR_LIST <<< "${PR_NUMBERS}" + for PR_NUMBER in "${PR_LIST[@]}"; do + PR_NUMBER=$(echo "$PR_NUMBER" | tr -d ' ') + BODY="${BODY}\n- ${SOURCE_REPO}#${PR_NUMBER}" + done + fi + + BODY="${BODY}\n\n---\n\nThis PR was generated from a [GitHub Actions workflow run](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}) triggered by @${GITHUB_ACTOR}." + + if [ "${PR_TARGET}" = "upstream" ]; then + PR_REPO="${UPSTREAM_REPO}" + PR_HEAD="${GITHUB_REPOSITORY_OWNER}:${BACKPORT_BRANCH}" + else + PR_REPO="${GITHUB_REPOSITORY}" + PR_HEAD="${BACKPORT_BRANCH}" + fi + + PR_URL=$(gh pr create \ + --repo "${PR_REPO}" \ + --base "${MATRIX_BRANCH}" \ + --head "${PR_HEAD}" \ + --title "$PR_TITLE" \ + --assignee "${GITHUB_ACTOR}" \ + --draft \ + --body "$(echo -e "$BODY")") + + if gh label list --repo "${PR_REPO}" --json name --jq '[.[].name] | contains(["Auto-backport"])' | grep -q 'true'; then + gh pr edit "$PR_URL" --repo "${PR_REPO}" --add-label 'Auto-backport' + else + echo "::notice::The 'Auto-backport' label does not exist on ${PR_REPO}. Consider adding it so that backport pull requests can be identified easily." + fi + + echo "url=${PR_URL}" >> "$GITHUB_OUTPUT" + + - name: Save summary row + if: always() + env: + MATRIX_BRANCH: ${{ matrix.branch }} + PR_URL: ${{ steps.create-pr.outputs.url }} + COMMIT_SHA: ${{ inputs.commit-sha }} + PR_NUMBERS: ${{ inputs.pr_numbers }} + PR_NAME: ${{ inputs.pr-name }} + run: | + mkdir -p summary-row + SAFE_BRANCH=$(echo "${MATRIX_BRANCH}" | tr '.' '-') + MERGE_RESULTS="" + + if [ -f "apply-result/${SAFE_BRANCH}.txt" ]; then + MERGE_RESULTS=$(grep '^merge_results=' "apply-result/${SAFE_BRANCH}.txt" | cut -d= -f2-) + fi + + RUN_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" + + if [ -n "${PR_URL}" ]; then + if [ -n "${PR_NUMBERS}" ] && [ -z "${COMMIT_SHA}" ]; then + PR_DISPLAY="${PR_URL}" + else + if [ -n "${PR_NAME}" ]; then + PR_TITLE="${PR_NAME} - ${MATRIX_BRANCH} branch" + else + PR_TITLE="Backport to ${MATRIX_BRANCH}" + fi + PR_DISPLAY="[${PR_TITLE}](${PR_URL})" + fi + else + PR_DISPLAY="[View log](${RUN_URL})" + fi + + if [ -n "${PR_NUMBERS}" ] && [ -z "${COMMIT_SHA}" ]; then + IFS=',' read -ra PR_LIST <<< "${PR_NUMBERS}" + ROW="| \`${MATRIX_BRANCH}\` |" + for PR_NUM in "${PR_LIST[@]}"; do + PR_NUM=$(echo "$PR_NUM" | tr -d ' ') + STATUS=$(echo "${MERGE_RESULTS}" | tr ' ' '\n' | grep "^${PR_NUM}=" | cut -d= -f2) + ROW="${ROW} ${STATUS:-❌} |" + done + ROW="${ROW} ${PR_DISPLAY} |" + else + ROW="| \`${MATRIX_BRANCH}\` | ${PR_DISPLAY} |" + fi + + printf '%s\n' "$ROW" > "summary-row/${SAFE_BRANCH}.txt" + + - name: Upload summary row + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: summary-row-${{ matrix.branch }} + path: summary-row/ + retention-days: 1 + + # Aggregates results from all matrix jobs into a single workflow summary. + # + # Performs the following steps: + # - Downloads pre-rendered summary row artifacts from all create-pr jobs. + # - Writes the table header and appends all rows to the workflow summary. + report: + name: Backport report + needs: [ 'validate-inputs', 'backport', 'create-pr' ] + runs-on: ubuntu-24.04 + if: ${{ always() && needs.validate-inputs.result != 'failure' }} + steps: + - name: Download summary rows + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + pattern: summary-row-* + path: summary-rows/ + merge-multiple: true + continue-on-error: true + + - name: Write summary + env: + COMMIT_SHA: ${{ inputs.commit-sha }} + PR_NUMBERS: ${{ inputs.pr_numbers }} + run: | + if [ -n "${PR_NUMBERS}" ] && [ -z "${COMMIT_SHA}" ]; then + IFS=',' read -ra PR_LIST <<< "${PR_NUMBERS}" + + HEADER="| Branch |" + SEPARATOR="| :--- |" + for PR_NUM in "${PR_LIST[@]}"; do + PR_NUM=$(echo "$PR_NUM" | tr -d ' ') + HEADER="${HEADER} #${PR_NUM} |" + SEPARATOR="${SEPARATOR} :---: |" + done + HEADER="${HEADER} Pull Request |" + SEPARATOR="${SEPARATOR} :--- |" + + printf '%s\n%s\n' "$HEADER" "$SEPARATOR" >> "$GITHUB_STEP_SUMMARY" + else + printf '| Branch | Pull Request |\n| :--- | :--- |\n' >> "$GITHUB_STEP_SUMMARY" + fi + + for ROW_FILE in $(ls summary-rows/*.txt 2>/dev/null | sort); do + cat "${ROW_FILE}" >> "$GITHUB_STEP_SUMMARY" + done diff --git a/src/wp-content/themes/twentytwentyone/package-lock.json b/src/wp-content/themes/twentytwentyone/package-lock.json index 3f412536967cc..d00d4653c4e9c 100644 --- a/src/wp-content/themes/twentytwentyone/package-lock.json +++ b/src/wp-content/themes/twentytwentyone/package-lock.json @@ -11,7 +11,7 @@ "devDependencies": { "@wordpress/browserslist-config": "^6.34.0", "@wordpress/eslint-plugin": "^22.20.0", - "@wordpress/stylelint-config": "^21.30.0", + "@wordpress/stylelint-config": "^23.37.0", "autoprefixer": "^10.4.22", "chokidar-cli": "^3.0.0", "eslint": "^8.57.1", @@ -2654,6 +2654,53 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/@stylistic/stylelint-plugin": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-3.1.3.tgz", + "integrity": "sha512-85fsmzgsIVmyG3/GFrjuYj6Cz8rAM7IZiPiXCMiSMfoDOC1lOrzrXPDk24WqviAghnPqGpx8b0caK2PuewWGFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.1", + "@csstools/css-tokenizer": "^3.0.1", + "@csstools/media-query-list-parser": "^3.0.1", + "is-plain-object": "^5.0.0", + "postcss": "^8.4.41", + "postcss-selector-parser": "^6.1.2", + "postcss-value-parser": "^4.2.0", + "style-search": "^0.1.0" + }, + "engines": { + "node": "^18.12 || >=20.9" + }, + "peerDependencies": { + "stylelint": "^16.8.0" + } + }, + "node_modules/@stylistic/stylelint-plugin/node_modules/@csstools/media-query-list-parser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-3.0.1.tgz", + "integrity": "sha512-HNo8gGD02kHmcbX6PvCoUuOQvn4szyB9ca63vZHKX5A81QytgDG4oxG4IaEfHTlEZSZ6MjPEMWIVU+zF2PZcgw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.1", + "@csstools/css-tokenizer": "^3.0.1" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -2686,6 +2733,34 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.29", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.29.tgz", + "integrity": "sha512-ch0qJdr2JY0r04NXSprbK6TXOgnaJ1Tz23fm5W+z0/CBah6BSBc3n96h7K9GOtwh0HrilNWHIBzE1Ko4Dcw/Wg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, "node_modules/@types/semver": { "version": "7.5.5", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.5.tgz", @@ -2934,6 +3009,37 @@ "npm": ">=8.19.2" } }, + "node_modules/@wordpress/element": { + "version": "6.46.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.46.0.tgz", + "integrity": "sha512-hjnrqZi0cZVdkmN0xQavKfSQJYAkb9pVSnDPpuX65OLxeD9/EWkIXvFzBb+nH8c4NzKKSqQU96XCTQrH37OCIA==", + "dev": true, + "license": "GPL-2.0-or-later", + "dependencies": { + "@types/react": "^18.3.27", + "@types/react-dom": "^18.3.1", + "@wordpress/escape-html": "^3.46.0", + "change-case": "^4.1.2", + "is-plain-object": "^5.0.0", + "react": "^18.3.0", + "react-dom": "^18.3.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/escape-html": { + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.46.0.tgz", + "integrity": "sha512-SzrVQwLQBZdaSStYVpTKeYqp97NABz1w551T8me3msDDsfhWWPhSZiZTNaGZ6iqUNfOX2uKyZsqXedvkqwLHqA==", + "dev": true, + "license": "GPL-2.0-or-later", + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/eslint-plugin": { "version": "22.20.0", "resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-22.20.0.tgz", @@ -2992,52 +3098,87 @@ "prettier": ">=3" } }, + "node_modules/@wordpress/private-apis": { + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.46.0.tgz", + "integrity": "sha512-l8dsEuxq6CrtsI7Twfpn6CbPHmGBUQoGN4oLPJG1Bqsr1yXXLU/bEx9KAQN9emxRjXaELPsn7x7TVx0TUoKyJw==", + "dev": true, + "license": "GPL-2.0-or-later", + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/stylelint-config": { - "version": "21.41.0", - "resolved": "https://registry.npmjs.org/@wordpress/stylelint-config/-/stylelint-config-21.41.0.tgz", - "integrity": "sha512-2wxFu8ICeRGF3Lxz7H7o2SU1u6pTI4mjuog39DgtCNb+v+f6yhgREDuNQEeti3Svb0rjj63AJ7r2CqLZk+EQIQ==", + "version": "23.37.0", + "resolved": "https://registry.npmjs.org/@wordpress/stylelint-config/-/stylelint-config-23.37.0.tgz", + "integrity": "sha512-1IYD9qro2/+h8+jGosIFzxQtjEEyTT7t679LzzoWdeWX7kacnIdDv4QZzK2JAzW+PaZit3cnZQgqxZvgBoXk4w==", "dev": true, "license": "MIT", "dependencies": { - "stylelint-config-recommended": "^6.0.0", - "stylelint-config-recommended-scss": "^5.0.2" + "@stylistic/stylelint-plugin": "^3.0.1", + "@wordpress/theme": "^0.12.0", + "stylelint-config-recommended": "^14.0.1", + "stylelint-config-recommended-scss": "^14.1.0" }, "engines": { - "node": ">=14" + "node": ">=18.12.0", + "npm": ">=8.19.2" }, "peerDependencies": { - "stylelint": "^14.2" + "stylelint": "^16.8.2", + "stylelint-scss": "^6.4.0" } }, "node_modules/@wordpress/stylelint-config/node_modules/stylelint-config-recommended-scss": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-5.0.2.tgz", - "integrity": "sha512-b14BSZjcwW0hqbzm9b0S/ScN2+3CO3O4vcMNOw2KGf8lfVSwJ4p5TbNEXKwKl1+0FMtgRXZj6DqVUe/7nGnuBg==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-14.1.0.tgz", + "integrity": "sha512-bhaMhh1u5dQqSsf6ri2GVWWQW5iUjBYgcHkh7SgDDn92ijoItC/cfO/W+fpXshgTQWhwFkP1rVcewcv4jaftRg==", "dev": true, "license": "MIT", "dependencies": { - "postcss-scss": "^4.0.2", - "stylelint-config-recommended": "^6.0.0", - "stylelint-scss": "^4.0.0" + "postcss-scss": "^4.0.9", + "stylelint-config-recommended": "^14.0.1", + "stylelint-scss": "^6.4.0" + }, + "engines": { + "node": ">=18.12.0" }, "peerDependencies": { - "stylelint": "^14.0.0" + "postcss": "^8.3.3", + "stylelint": "^16.6.1" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + } } }, - "node_modules/@wordpress/stylelint-config/node_modules/stylelint-scss": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-4.7.0.tgz", - "integrity": "sha512-TSUgIeS0H3jqDZnby1UO1Qv3poi1N8wUYIJY6D1tuUq2MN3lwp/rITVo0wD+1SWTmRm0tNmGO0b7nKInnqF6Hg==", + "node_modules/@wordpress/theme": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@wordpress/theme/-/theme-0.12.0.tgz", + "integrity": "sha512-AmEVO0B+kI9tsxkLnna/S+7yi+EPCMTuaPqagje7pnlXeDfykVQfeDeWJfU+QvhcqHXCySn89vvw1Ihep0rj7w==", "dev": true, - "license": "MIT", + "license": "GPL-2.0-or-later", "dependencies": { - "postcss-media-query-parser": "^0.2.3", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-selector-parser": "^6.0.11", - "postcss-value-parser": "^4.2.0" + "@wordpress/element": "^6.45.0", + "@wordpress/private-apis": "^1.45.0", + "colorjs.io": "^0.6.0", + "memize": "^2.1.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" }, "peerDependencies": { - "stylelint": "^14.5.1 || ^15.0.0" + "react": "^18.0.0", + "react-dom": "^18.0.0", + "stylelint": "^16.8.2" + }, + "peerDependenciesMeta": { + "stylelint": { + "optional": true + } } }, "node_modules/@wordpress/warning": { @@ -3941,6 +4082,17 @@ "node": ">=6" } }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, "node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -4001,6 +4153,18 @@ ], "license": "CC-BY-4.0" }, + "node_modules/capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -4015,6 +4179,27 @@ "node": ">=4" } }, + "node_modules/change-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", + "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "camel-case": "^4.1.2", + "capital-case": "^1.0.4", + "constant-case": "^3.0.4", + "dot-case": "^3.0.4", + "header-case": "^2.0.4", + "no-case": "^3.0.4", + "param-case": "^3.0.4", + "pascal-case": "^3.1.2", + "path-case": "^3.0.4", + "sentence-case": "^3.0.4", + "snake-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/chokidar": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", @@ -4086,6 +4271,17 @@ "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", "dev": true }, + "node_modules/colorjs.io": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.6.1.tgz", + "integrity": "sha512-8lyR2wHzuIykCpqHKgluGsqQi5iDm3/a2IgP2GBZrasn2sBRkE4NOGsglZxWLs/jZQoNkmA/KM/8NV16rLUdBg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/color" + } + }, "node_modules/comment-parser": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", @@ -4101,6 +4297,18 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "node_modules/constant-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", + "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case": "^2.0.2" + } + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -4233,6 +4441,13 @@ "postcss": "^8.4.32" } }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -4405,6 +4620,17 @@ "node": ">=0.10.0" } }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.249", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.249.tgz", @@ -5894,6 +6120,17 @@ "node": ">= 0.4" } }, + "node_modules/header-case": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", + "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "capital-case": "^1.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -6720,6 +6957,16 @@ "loose-envify": "cli.js" } }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -6762,6 +7009,13 @@ "dev": true, "license": "CC0-1.0" }, + "node_modules/memize": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/memize/-/memize-2.1.1.tgz", + "integrity": "sha512-8Nl+i9S5D6KXnruM03Jgjb+LwSupvR13WBr4hJegaaEyobvowCVupi79y2WSiWvO1mzBWxPwEYE5feCe8vyA5w==", + "dev": true, + "license": "MIT" + }, "node_modules/memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", @@ -6962,6 +7216,17 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, "node_modules/node-addon-api": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", @@ -7950,6 +8215,17 @@ "node": ">=6" } }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -7980,6 +8256,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", + "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -8736,6 +9034,20 @@ "node": ">=0.10.0" } }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -9304,6 +9616,16 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, "node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -9319,6 +9641,18 @@ "node": ">=10" } }, + "node_modules/sentence-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", + "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -9459,6 +9793,17 @@ "node": ">=8" } }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -9854,13 +10199,26 @@ } }, "node_modules/stylelint-config-recommended": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-6.0.0.tgz", - "integrity": "sha512-ZorSSdyMcxWpROYUvLEMm0vSZud2uB7tX1hzBZwvVY9SV/uly4AvvJPPhCcymZL3fcQhEQG5AELmrxWqtmzacw==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-14.0.1.tgz", + "integrity": "sha512-bLvc1WOz/14aPImu/cufKAZYfXs/A/owZfSMZ4N+16WGXLoX5lOir53M6odBxvhgmgdxCVnNySJmZKx73T93cg==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + }, + { + "type": "github", + "url": "https://github.com/sponsors/stylelint" + } + ], "license": "MIT", + "engines": { + "node": ">=18.12.0" + }, "peerDependencies": { - "stylelint": "^14.0.0" + "stylelint": "^16.1.0" } }, "node_modules/stylelint-config-recommended-scss": { @@ -10497,6 +10855,26 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", + "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/upper-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", + "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -12279,6 +12657,30 @@ "tslib": "^2.6.0" } }, + "@stylistic/stylelint-plugin": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-3.1.3.tgz", + "integrity": "sha512-85fsmzgsIVmyG3/GFrjuYj6Cz8rAM7IZiPiXCMiSMfoDOC1lOrzrXPDk24WqviAghnPqGpx8b0caK2PuewWGFg==", + "dev": true, + "requires": { + "@csstools/css-parser-algorithms": "^3.0.1", + "@csstools/css-tokenizer": "^3.0.1", + "@csstools/media-query-list-parser": "^3.0.1", + "is-plain-object": "^5.0.0", + "postcss": "^8.4.41", + "postcss-selector-parser": "^6.1.2", + "postcss-value-parser": "^4.2.0", + "style-search": "^0.1.0" + }, + "dependencies": { + "@csstools/media-query-list-parser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-3.0.1.tgz", + "integrity": "sha512-HNo8gGD02kHmcbX6PvCoUuOQvn4szyB9ca63vZHKX5A81QytgDG4oxG4IaEfHTlEZSZ6MjPEMWIVU+zF2PZcgw==", + "dev": true + } + } + }, "@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -12309,6 +12711,28 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, + "@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "dev": true + }, + "@types/react": { + "version": "18.3.29", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.29.tgz", + "integrity": "sha512-ch0qJdr2JY0r04NXSprbK6TXOgnaJ1Tz23fm5W+z0/CBah6BSBc3n96h7K9GOtwh0HrilNWHIBzE1Ko4Dcw/Wg==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "csstype": "^3.2.2" + } + }, + "@types/react-dom": { + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "dev": true + }, "@types/semver": { "version": "7.5.5", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.5.tgz", @@ -12454,6 +12878,27 @@ "integrity": "sha512-pmcCkqG2jW+UUBSkX7rSZS33mcW6M0fKcJPD40TlK2cUZvECS5TDa2BC/b80PfIsT2kSw+Z9Wv+8eyX6I8HGjQ==", "dev": true }, + "@wordpress/element": { + "version": "6.46.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.46.0.tgz", + "integrity": "sha512-hjnrqZi0cZVdkmN0xQavKfSQJYAkb9pVSnDPpuX65OLxeD9/EWkIXvFzBb+nH8c4NzKKSqQU96XCTQrH37OCIA==", + "dev": true, + "requires": { + "@types/react": "^18.3.27", + "@types/react-dom": "^18.3.1", + "@wordpress/escape-html": "^3.46.0", + "change-case": "^4.1.2", + "is-plain-object": "^5.0.0", + "react": "^18.3.0", + "react-dom": "^18.3.0" + } + }, + "@wordpress/escape-html": { + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.46.0.tgz", + "integrity": "sha512-SzrVQwLQBZdaSStYVpTKeYqp97NABz1w551T8me3msDDsfhWWPhSZiZTNaGZ6iqUNfOX2uKyZsqXedvkqwLHqA==", + "dev": true + }, "@wordpress/eslint-plugin": { "version": "22.20.0", "resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-22.20.0.tgz", @@ -12485,41 +12930,49 @@ "integrity": "sha512-vrcjpVegYSwTSC8JfcE/qmmv1lsqDDhKvLqT8rMhW4DiogH8sVThJ1w5o2qOELXON2ArqfAxW8+DVmHsTPCUzQ==", "dev": true }, + "@wordpress/private-apis": { + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.46.0.tgz", + "integrity": "sha512-l8dsEuxq6CrtsI7Twfpn6CbPHmGBUQoGN4oLPJG1Bqsr1yXXLU/bEx9KAQN9emxRjXaELPsn7x7TVx0TUoKyJw==", + "dev": true + }, "@wordpress/stylelint-config": { - "version": "21.41.0", - "resolved": "https://registry.npmjs.org/@wordpress/stylelint-config/-/stylelint-config-21.41.0.tgz", - "integrity": "sha512-2wxFu8ICeRGF3Lxz7H7o2SU1u6pTI4mjuog39DgtCNb+v+f6yhgREDuNQEeti3Svb0rjj63AJ7r2CqLZk+EQIQ==", + "version": "23.37.0", + "resolved": "https://registry.npmjs.org/@wordpress/stylelint-config/-/stylelint-config-23.37.0.tgz", + "integrity": "sha512-1IYD9qro2/+h8+jGosIFzxQtjEEyTT7t679LzzoWdeWX7kacnIdDv4QZzK2JAzW+PaZit3cnZQgqxZvgBoXk4w==", "dev": true, "requires": { - "stylelint-config-recommended": "^6.0.0", - "stylelint-config-recommended-scss": "^5.0.2" + "@stylistic/stylelint-plugin": "^3.0.1", + "@wordpress/theme": "^0.12.0", + "stylelint-config-recommended": "^14.0.1", + "stylelint-config-recommended-scss": "^14.1.0" }, "dependencies": { "stylelint-config-recommended-scss": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-5.0.2.tgz", - "integrity": "sha512-b14BSZjcwW0hqbzm9b0S/ScN2+3CO3O4vcMNOw2KGf8lfVSwJ4p5TbNEXKwKl1+0FMtgRXZj6DqVUe/7nGnuBg==", - "dev": true, - "requires": { - "postcss-scss": "^4.0.2", - "stylelint-config-recommended": "^6.0.0", - "stylelint-scss": "^4.0.0" - } - }, - "stylelint-scss": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-4.7.0.tgz", - "integrity": "sha512-TSUgIeS0H3jqDZnby1UO1Qv3poi1N8wUYIJY6D1tuUq2MN3lwp/rITVo0wD+1SWTmRm0tNmGO0b7nKInnqF6Hg==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-14.1.0.tgz", + "integrity": "sha512-bhaMhh1u5dQqSsf6ri2GVWWQW5iUjBYgcHkh7SgDDn92ijoItC/cfO/W+fpXshgTQWhwFkP1rVcewcv4jaftRg==", "dev": true, "requires": { - "postcss-media-query-parser": "^0.2.3", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-selector-parser": "^6.0.11", - "postcss-value-parser": "^4.2.0" + "postcss-scss": "^4.0.9", + "stylelint-config-recommended": "^14.0.1", + "stylelint-scss": "^6.4.0" } } } }, + "@wordpress/theme": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@wordpress/theme/-/theme-0.12.0.tgz", + "integrity": "sha512-AmEVO0B+kI9tsxkLnna/S+7yi+EPCMTuaPqagje7pnlXeDfykVQfeDeWJfU+QvhcqHXCySn89vvw1Ihep0rj7w==", + "dev": true, + "requires": { + "@wordpress/element": "^6.45.0", + "@wordpress/private-apis": "^1.45.0", + "colorjs.io": "^0.6.0", + "memize": "^2.1.0" + } + }, "@wordpress/warning": { "version": "3.34.0", "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.34.0.tgz", @@ -13139,6 +13592,16 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, + "camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "requires": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -13174,6 +13637,17 @@ "integrity": "sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==", "dev": true }, + "capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -13185,6 +13659,26 @@ "supports-color": "^5.3.0" } }, + "change-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", + "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", + "dev": true, + "requires": { + "camel-case": "^4.1.2", + "capital-case": "^1.0.4", + "constant-case": "^3.0.4", + "dot-case": "^3.0.4", + "header-case": "^2.0.4", + "no-case": "^3.0.4", + "param-case": "^3.0.4", + "pascal-case": "^3.1.2", + "path-case": "^3.0.4", + "sentence-case": "^3.0.4", + "snake-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "chokidar": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", @@ -13245,6 +13739,12 @@ "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", "dev": true }, + "colorjs.io": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.6.1.tgz", + "integrity": "sha512-8lyR2wHzuIykCpqHKgluGsqQi5iDm3/a2IgP2GBZrasn2sBRkE4NOGsglZxWLs/jZQoNkmA/KM/8NV16rLUdBg==", + "dev": true + }, "comment-parser": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", @@ -13257,6 +13757,17 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "constant-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", + "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case": "^2.0.2" + } + }, "convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -13344,6 +13855,12 @@ "integrity": "sha512-ZIP71eQgG9JwjVZsTPSqhc6GHgEr53uJ7tK5///VfyWj6Xp2DBmixWHqJgPno+PqATzn48pL42ww9x5SSGmhZg==", "dev": true }, + "csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true + }, "damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -13457,6 +13974,16 @@ "esutils": "^2.0.2" } }, + "dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "electron-to-chromium": { "version": "1.5.249", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.249.tgz", @@ -14508,6 +15035,16 @@ "function-bind": "^1.1.2" } }, + "header-case": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", + "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", + "dev": true, + "requires": { + "capital-case": "^1.0.4", + "tslib": "^2.0.3" + } + }, "hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -15117,6 +15654,15 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -15144,6 +15690,12 @@ "integrity": "sha512-T2LPsjgUE/tgMmRXREVmwsux89DwWfNjiynOeXuLd2mX6jphGQ2YE3Ukz7LQ2VOFKiVZU/Ee1GqzHiipZCjymw==", "dev": true }, + "memize": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/memize/-/memize-2.1.1.tgz", + "integrity": "sha512-8Nl+i9S5D6KXnruM03Jgjb+LwSupvR13WBr4hJegaaEyobvowCVupi79y2WSiWvO1mzBWxPwEYE5feCe8vyA5w==", + "dev": true + }, "memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", @@ -15283,6 +15835,16 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, "node-addon-api": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", @@ -15997,6 +16559,16 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -16018,6 +16590,26 @@ "lines-and-columns": "^1.1.6" } }, + "pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "path-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", + "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", + "dev": true, + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -16471,6 +17063,16 @@ "loose-envify": "^1.1.0" } }, + "react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + } + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -16862,6 +17464,15 @@ } } }, + "scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0" + } + }, "semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -16871,6 +17482,17 @@ "lru-cache": "^6.0.0" } }, + "sentence-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", + "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -16977,6 +17599,16 @@ } } }, + "snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dev": true, + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -17333,9 +17965,9 @@ } }, "stylelint-config-recommended": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-6.0.0.tgz", - "integrity": "sha512-ZorSSdyMcxWpROYUvLEMm0vSZud2uB7tX1hzBZwvVY9SV/uly4AvvJPPhCcymZL3fcQhEQG5AELmrxWqtmzacw==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-14.0.1.tgz", + "integrity": "sha512-bLvc1WOz/14aPImu/cufKAZYfXs/A/owZfSMZ4N+16WGXLoX5lOir53M6odBxvhgmgdxCVnNySJmZKx73T93cg==", "dev": true }, "stylelint-config-recommended-scss": { @@ -17712,6 +18344,24 @@ "picocolors": "^1.1.1" } }, + "upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", + "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "upper-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", + "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", diff --git a/src/wp-content/themes/twentytwentyone/package.json b/src/wp-content/themes/twentytwentyone/package.json index 2e84df4ffb3b4..0dd5370225508 100644 --- a/src/wp-content/themes/twentytwentyone/package.json +++ b/src/wp-content/themes/twentytwentyone/package.json @@ -19,7 +19,7 @@ "devDependencies": { "@wordpress/browserslist-config": "^6.34.0", "@wordpress/eslint-plugin": "^22.20.0", - "@wordpress/stylelint-config": "^21.30.0", + "@wordpress/stylelint-config": "^23.37.0", "autoprefixer": "^10.4.22", "chokidar-cli": "^3.0.0", "eslint": "^8.57.1",