Commit 81d39a336b for woocommerce

commit 81d39a336b55041758814f7aabd8b7e7634e7b95
Author: Mario Santos <34552881+SantosGuillamot@users.noreply.github.com>
Date:   Wed Feb 25 09:16:17 2026 +0100

    iAPI cart store: Refresh cart on page load and store fresh nonce (#62892)

    * Remove `nonce` initialization from the server

    * Handle `nonce` in the cart store

    * Remove unnecessary init calls

    * Add e2e tests

    * Change `isNonceReady`

    * Revert "Add e2e tests"

    This reverts commit 3346572aee18559a66b2ee47a8ecd957c6882f99.

    * Try new e2e test

    * Fix test route

    * Reduce timeout

    * Change test directory

    * Add changefile(s) from automation for the following project(s): woocommerce

    * Fix linter and change expiricy time

    * Add `eslint-disable` to test

    * Move `isNonceReady` inside `sendCartRequest`

    * Update nonce after each request

    * Update e2e test

    * Update e2e test to ensure consistency

    * Fix linting

    * Fix all types on cart.ts store

    * Remove `onResponse` in favor of overriding `fetch`

    * Fix how nonceReady is handled

    * Try: Fix `@wordpress/a11y` version

    * Trigger CI

    ---------

    Co-authored-by: woocommercebot <woocommercebot@users.noreply.github.com>
    Co-authored-by: luisherranz <luisherranz@gmail.com>

diff --git a/plugins/woocommerce/changelog/62892-wooplug-6129-iapi-cart-store-refresh-cart-on-page-load-and-store-fresh b/plugins/woocommerce/changelog/62892-wooplug-6129-iapi-cart-store-refresh-cart-on-page-load-and-store-fresh
new file mode 100644
index 0000000000..f4bfd5956b
--- /dev/null
+++ b/plugins/woocommerce/changelog/62892-wooplug-6129-iapi-cart-store-refresh-cart-on-page-load-and-store-fresh
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix add to cart not working on stale nonces on cached pages
\ No newline at end of file
diff --git a/plugins/woocommerce/client/blocks/assets/js/base/stores/woocommerce/cart.ts b/plugins/woocommerce/client/blocks/assets/js/base/stores/woocommerce/cart.ts
index 891f888c2a..ba1f516136 100644
--- a/plugins/woocommerce/client/blocks/assets/js/base/stores/woocommerce/cart.ts
+++ b/plugins/woocommerce/client/blocks/assets/js/base/stores/woocommerce/cart.ts
@@ -2,6 +2,7 @@
  * External dependencies
  */
 import { getConfig, store } from '@wordpress/interactivity';
+import type { AsyncAction, TypeYield } from '@wordpress/interactivity';
 import type {
 	Cart,
 	CartItem,
@@ -106,20 +107,23 @@ export type Store = {
 		};
 	};
 	actions: {
-		removeCartItem: ( key: string ) => void;
+		removeCartItem: ( key: string ) => Promise< void >;
 		addCartItem: (
 			args: ClientCartItem,
 			options?: CartUpdateOptions
-		) => void;
+		) => Promise< void >;
 		batchAddCartItems: (
 			items: ClientCartItem[],
 			options?: CartUpdateOptions
-		) => void;
+		) => Promise< void >;
 		// Todo: Check why if I switch to an async function here the types of the store stop working.
-		refreshCartItems: () => void;
-		waitForIdle: () => void;
-		showNoticeError: ( error: Error | ApiErrorResponse ) => void;
-		updateNotices: ( notices: Notice[], removeOthers?: boolean ) => void;
+		refreshCartItems: () => Promise< void >;
+		waitForIdle: () => Promise< void >;
+		showNoticeError: ( error: Error | ApiErrorResponse ) => Promise< void >;
+		updateNotices: (
+			notices: Notice[],
+			removeOthers?: boolean
+		) => Promise< void >;
 	};
 };

@@ -173,13 +177,13 @@ const getInfoNoticesFromCartUpdates = (
 		cartItemsPendingDelete: pendingDelete = [],
 	} = quantityChanges;

-	const autoDeletedToNotify = oldItems.filter(
-		( old ) =>
-			old.key &&
-			isCartItem( old ) &&
-			! newItems.some( ( item ) => old.key === item.key ) &&
-			! pendingDelete.includes( old.key )
-	);
+	const autoDeletedToNotify = oldItems
+		.filter( isCartItem )
+		.filter(
+			( old ) =>
+				! newItems.some( ( item ) => old.key === item.key ) &&
+				! pendingDelete.includes( old.key )
+		);

 	const autoUpdatedToNotify = newItems.filter( ( item ) => {
 		if ( ! isCartItem( item ) ) {
@@ -191,6 +195,7 @@ const getInfoNoticesFromCartUpdates = (
 					item.quantity !== old.quantity
 			: ! pendingAdd.includes( item.id );
 	} );
+
 	return [
 		...autoDeletedToNotify.map( ( item ) =>
 			// TODO: move the message template to iAPI config.
@@ -246,6 +251,10 @@ const doesCartItemMatchAttributes = (

 let pendingRefresh = false;
 let refreshTimeout = 3000;
+let resolveNonceReady: ( () => void ) | null = null;
+const isNonceReady = new Promise< void >( ( resolve ) => {
+	resolveNonceReady = resolve;
+} );

 function emitSyncEvent( {
 	quantityChanges,
@@ -275,10 +284,11 @@ let cartQueue: MutationQueue< Cart > | null = null;
  *
  * Handles optimistic updates, request queuing, and state reconciliation.
  */
-function sendCartRequest(
+async function sendCartRequest(
 	stateRef: Store[ 'state' ],
 	options: MutationRequest< Cart >
 ): Promise< MutationResult< Cart > > {
+	await isNonceReady;
 	// Lazily initialize queue on first use.
 	if ( ! cartQueue ) {
 		cartQueue = createMutationQueue< Cart >( {
@@ -293,6 +303,12 @@ function sendCartRequest(
 			commit: ( serverState ) => {
 				stateRef.cart = serverState;
 			},
+			fetchHandler: async ( ...args ) => {
+				const response = await fetch( ...args );
+				stateRef.nonce =
+					response.headers.get( 'Nonce' ) || stateRef.nonce;
+				return response;
+			},
 		} );
 	}

@@ -304,7 +320,7 @@ const { state, actions } = store< Store >(
 	'woocommerce',
 	{
 		actions: {
-			*removeCartItem( key: string ) {
+			*removeCartItem( key: string ): AsyncAction< void > {
 				// Track what changes we're making for notice comparison.
 				const quantityChanges: QuantityChanges = {
 					cartItemsPendingDelete: [ key ],
@@ -314,7 +330,7 @@ const { state, actions } = store< Store >(
 				let cartAfterOptimistic: typeof state.cart | null = null;

 				try {
-					const result = yield sendCartRequest( state, {
+					const result = ( yield sendCartRequest( state, {
 						path: '/wc/store/v1/cart/remove-item',
 						method: 'POST',
 						body: { key },
@@ -335,7 +351,7 @@ const { state, actions } = store< Store >(
 								emitSyncEvent( { quantityChanges } );
 							}
 						},
-					} );
+					} ) ) as TypeYield< typeof sendCartRequest >;

 					// Show notices from server response.
 					const cart = result.data as Cart;
@@ -360,7 +376,7 @@ const { state, actions } = store< Store >(
 			*addCartItem(
 				{ id, key, quantity, quantityToAdd, variation }: ClientCartItem,
 				{ showCartUpdatesNotices = true }: CartUpdateOptions = {}
-			) {
+			): AsyncAction< void > {
 				if ( quantity !== undefined && quantityToAdd !== undefined ) {
 					throw new Error(
 						'addCartItem: pass either quantity or quantityToAdd, not both.'
@@ -441,7 +457,7 @@ const { state, actions } = store< Store >(
 				let cartAfterOptimistic: typeof state.cart | null = null;

 				try {
-					const result = yield sendCartRequest( state, {
+					const result = ( yield sendCartRequest( state, {
 						path: `/wc/store/v1/cart/${ endpoint }`,
 						method: 'POST',
 						body: itemToSend,
@@ -477,7 +493,7 @@ const { state, actions } = store< Store >(
 								emitSyncEvent( { quantityChanges } );
 							}
 						},
-					} );
+					} ) ) as TypeYield< typeof sendCartRequest >;

 					// Success - handle side effects that don't trigger refreshCartItems
 					const cart = result.data as Cart;
@@ -506,7 +522,10 @@ const { state, actions } = store< Store >(
 						'woocommerce'
 					) as WooCommerceConfig;
 					if ( messages?.addedToCartText ) {
-						const { speak } = yield a11yModulePromise;
+						const { speak } =
+							( yield a11yModulePromise ) as Awaited<
+								typeof a11yModulePromise
+							>;
 						speak( messages.addedToCartText, 'polite' );
 					}
 				} catch ( error ) {
@@ -518,7 +537,7 @@ const { state, actions } = store< Store >(
 			*batchAddCartItems(
 				items: ClientCartItem[],
 				{ showCartUpdatesNotices = true }: CartUpdateOptions = {}
-			) {
+			): AsyncAction< void > {
 				const a11yModulePromise = import( '@wordpress/a11y' );
 				const quantityChanges: QuantityChanges = {};

@@ -588,18 +607,18 @@ const { state, actions } = store< Store >(
 							// succeeded (data is set from the last
 							// successful server state). Only the last
 							// item's callback fires to avoid duplicates.
-							onSettled: isLastItem
-								? ( { data } ) => {
-										if ( data ) {
-											triggerAddedToCartEvent( {
-												preserveCartData: true,
-											} );
-											emitSyncEvent( {
-												quantityChanges,
-											} );
-										}
-								  }
-								: undefined,
+							...( isLastItem && {
+								onSettled: ( { data } ) => {
+									if ( data ) {
+										triggerAddedToCartEvent( {
+											preserveCartData: true,
+										} );
+										emitSyncEvent( {
+											quantityChanges,
+										} );
+									}
+								},
+							} ),
 						} );
 					} );

@@ -608,9 +627,9 @@ const { state, actions } = store< Store >(
 						JSON.stringify( state.cart )
 					);

-					const results: PromiseSettledResult<
-						MutationResult< Cart >
-					>[] = yield Promise.allSettled( promises );
+					const results = ( yield Promise.allSettled(
+						promises
+					) ) as PromiseSettledResult< MutationResult< Cart > >[];

 					// Find the last successful result for notices/a11y.
 					const lastSuccess = [ ...results ]
@@ -644,7 +663,10 @@ const { state, actions } = store< Store >(
 							'woocommerce'
 						) as WooCommerceConfig;
 						if ( messages?.addedToCartText ) {
-							const { speak } = yield a11yModulePromise;
+							const { speak } =
+								( yield a11yModulePromise ) as Awaited<
+									typeof a11yModulePromise
+								>;
 							speak( messages.addedToCartText, 'polite' );
 						}
 					}
@@ -666,7 +688,7 @@ const { state, actions } = store< Store >(
 				}
 			},

-			*refreshCartItems() {
+			*refreshCartItems(): AsyncAction< void > {
 				// Skip if queue is processing - it will apply server state when done
 				if ( cartQueue?.getStatus().isProcessing ) {
 					return;
@@ -678,15 +700,24 @@ const { state, actions } = store< Store >(
 				pendingRefresh = true;

 				try {
-					const res: Response = yield fetch(
+					const res = ( yield fetch(
 						`${ state.restUrl }wc/store/v1/cart`,
 						{
 							method: 'GET',
 							cache: 'no-store',
 							headers: { 'Content-Type': 'application/json' },
 						}
-					);
-					const json: Cart = yield res.json();
+					) ) as TypeYield< typeof fetch >;
+
+					// Extract fresh nonce from response headers.
+					state.nonce = res.headers.get( 'Nonce' ) || state.nonce;
+
+					if ( resolveNonceReady ) {
+						resolveNonceReady();
+						resolveNonceReady = null;
+					}
+
+					const json = ( yield res.json() ) as Cart;

 					// Checks if the response contains an error.
 					if ( isApiErrorResponse( res, json ) )
@@ -714,13 +745,15 @@ const { state, actions } = store< Store >(
 				}
 			},

-			*waitForIdle() {
+			*waitForIdle(): AsyncAction< void > {
 				if ( cartQueue ) {
 					yield cartQueue.waitForIdle();
 				}
 			},

-			*showNoticeError( error: Error | ApiErrorResponse ) {
+			*showNoticeError(
+				error: Error | ApiErrorResponse
+			): AsyncAction< void > {
 				// Todo: Use the module exports instead of `store()` once the store-notices
 				// store is public.
 				yield import( '@woocommerce/stores/store-notices' );
@@ -749,7 +782,10 @@ const { state, actions } = store< Store >(
 				console.error( error );
 			},

-			*updateNotices( newNotices: Notice[] = [], removeOthers = false ) {
+			*updateNotices(
+				newNotices: Notice[] = [],
+				removeOthers = false
+			): AsyncAction< void > {
 				// Todo: Use the module exports instead of `store()` once the store-notices
 				// store is public.
 				yield import( '@woocommerce/stores/store-notices' );
@@ -780,6 +816,9 @@ const { state, actions } = store< Store >(
 	{ lock: true }
 );

+// Trigger initial cart refresh.
+actions.refreshCartItems();
+
 window.addEventListener(
 	'wc-blocks_store_sync_required',
 	async ( event: Event ) => {
diff --git a/plugins/woocommerce/client/blocks/assets/js/base/stores/woocommerce/mutation-batcher.ts b/plugins/woocommerce/client/blocks/assets/js/base/stores/woocommerce/mutation-batcher.ts
index e4ef2288ed..8164b5c072 100644
--- a/plugins/woocommerce/client/blocks/assets/js/base/stores/woocommerce/mutation-batcher.ts
+++ b/plugins/woocommerce/client/blocks/assets/js/base/stores/woocommerce/mutation-batcher.ts
@@ -41,6 +41,7 @@ type BatchItemResponse = {
 export type MutationQueueConfig< TState = unknown > = {
 	endpoint: string;
 	getHeaders: () => Record< string, string >;
+	fetchHandler?: typeof fetch;
 	takeSnapshot: () => TState;
 	rollback: ( snapshot: TState ) => void;
 	commit: ( serverState: TState ) => void;
@@ -56,7 +57,14 @@ type TrackedRequest< TState = unknown > = {
 export function createMutationQueue< TState >(
 	config: MutationQueueConfig< TState >
 ) {
-	const { endpoint, getHeaders, takeSnapshot, rollback, commit } = config;
+	const {
+		endpoint,
+		getHeaders,
+		takeSnapshot,
+		rollback,
+		commit,
+		fetchHandler = fetch,
+	} = config;

 	// Snapshot taken once at the start of each processing cycle.
 	let snapshot: TState | null = null;
@@ -215,7 +223,7 @@ export function createMutationQueue< TState >(
 				} )
 				.filter( Boolean );

-			const response = await fetch( endpoint, {
+			const response = await fetchHandler( endpoint, {
 				method: 'POST',
 				headers: {
 					'Content-Type': 'application/json',
diff --git a/plugins/woocommerce/client/blocks/package.json b/plugins/woocommerce/client/blocks/package.json
index 512b487114..ed89db50ee 100644
--- a/plugins/woocommerce/client/blocks/package.json
+++ b/plugins/woocommerce/client/blocks/package.json
@@ -169,8 +169,8 @@
 		"@wordpress/hooks": "wp-6.6",
 		"@wordpress/html-entities": "3.24.0",
 		"@wordpress/i18n": "4.45.0",
-		"@wordpress/interactivity": "github:woocommerce/gutenberg#interactivity-api-001&path:/packages/interactivity",
-		"@wordpress/interactivity-router": "github:woocommerce/gutenberg#interactivity-api-001&path:/packages/interactivity-router",
+		"@wordpress/interactivity": "^6.39.0",
+		"@wordpress/interactivity-router": "^2.39.0",
 		"@wordpress/is-shallow-equal": "4.24.0",
 		"@wordpress/jest-preset-default": "12.22.0",
 		"@wordpress/postcss-plugins-preset": "1.6.0",
@@ -261,7 +261,7 @@
 		"@woocommerce/email-editor": "workspace:*",
 		"@woocommerce/sanitize": "workspace:*",
 		"@woocommerce/tracks": "workspace:*",
-		"@wordpress/a11y": "4.22.0",
+		"@wordpress/a11y": "4.39.0",
 		"@wordpress/autop": "3.16.0",
 		"@wordpress/compose": "5.5.0",
 		"@wordpress/deprecated": "wp-6.6",
diff --git a/plugins/woocommerce/client/blocks/tests/e2e/plugins/short-nonce-life.php b/plugins/woocommerce/client/blocks/tests/e2e/plugins/short-nonce-life.php
new file mode 100644
index 0000000000..0af4a340bc
--- /dev/null
+++ b/plugins/woocommerce/client/blocks/tests/e2e/plugins/short-nonce-life.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Plugin Name: WooCommerce Blocks Test Short Nonce Life
+ * Description: Sets a very short nonce lifetime for testing nonce expiry scenarios.
+ * Plugin URI: https://github.com/woocommerce/woocommerce
+ * Author: WooCommerce
+ *
+ * @package woocommerce-blocks-test-short-nonce-life
+ */
+
+declare( strict_types=1 );
+
+/**
+ * Set nonce lifetime to 2 seconds to simulate cache expiry scenarios.
+ */
+add_filter(
+	'nonce_life',
+	function () {
+		return 2;
+	}
+);
diff --git a/plugins/woocommerce/client/blocks/tests/e2e/tests/cart/cart-store.block_theme.spec.ts b/plugins/woocommerce/client/blocks/tests/e2e/tests/cart/cart-store.block_theme.spec.ts
new file mode 100644
index 0000000000..c280a0f4d9
--- /dev/null
+++ b/plugins/woocommerce/client/blocks/tests/e2e/tests/cart/cart-store.block_theme.spec.ts
@@ -0,0 +1,82 @@
+/**
+ * External dependencies
+ */
+import { test, expect, guestFile } from '@woocommerce/e2e-utils';
+
+/**
+ * Internal dependencies
+ */
+import { REGULAR_PRICED_PRODUCT_NAME } from '../checkout/constants';
+
+test.describe( 'Cart Store', () => {
+	test.use( { storageState: guestFile } );
+
+	test.beforeEach( async ( { requestUtils } ) => {
+		await requestUtils.activatePlugin(
+			'woocommerce-blocks-test-short-nonce-life'
+		);
+	} );
+
+	test( 'should refresh nonce from Store API and use it for cart mutations', async ( {
+		page,
+		frontendUtils,
+	} ) => {
+		let refreshNonce: string | null = null;
+		let requestNonce: string | null = null;
+		let responseNonce: string | null = null;
+
+		// Intercept GET /cart (refreshCartItems) to capture the nonce.
+		await page.route( '**/wc/store/v1/cart**', async ( route ) => {
+			if ( route.request().method() === 'GET' ) {
+				const response = await route.fetch();
+				refreshNonce = response.headers().nonce || null;
+				await route.fulfill( { response } );
+			} else {
+				await route.continue();
+			}
+		} );
+
+		// Intercept batch requests to track which nonce the client sends
+		// and which nonce the server returns.
+		await page.route( '**/wc/store/v1/batch**', async ( route ) => {
+			requestNonce = route.request().headers().nonce || null;
+			const response = await route.fetch();
+			responseNonce = response.headers().nonce || null;
+			await route.fulfill( { response } );
+		} );
+
+		await frontendUtils.goToShop();
+
+		// Wait for the GET /cart request (refreshCartItems) to complete.
+		await page.waitForResponse( '**/wc/store/v1/cart**' );
+
+		// refreshCartItems should return a nonce.
+		expect( refreshNonce ).toBeTruthy();
+
+		// Adding a product should use the nonce from refreshCartItems.
+		await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
+		expect( requestNonce ).toBe( refreshNonce );
+
+		// Wait for the nonce to expire.
+		// eslint-disable-next-line playwright/no-wait-for-timeout, no-restricted-syntax
+		await page.waitForTimeout( 2000 );
+
+		// Adding another product should fail because it is using an expired nonce.
+		await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
+		await expect( page.getByText( 'Nonce is invalid.' ) ).toBeVisible();
+		const previousResponseNonce = responseNonce;
+
+		// Nonce should be updated now and the request should succeed.
+		await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
+		expect( requestNonce ).not.toBe( refreshNonce );
+		expect( requestNonce ).toBe( previousResponseNonce );
+
+		// Verify the product was actually added to the cart properly.
+		await frontendUtils.goToCart();
+		await expect(
+			page.getByLabel(
+				`Quantity of ${ REGULAR_PRICED_PRODUCT_NAME } in your cart.`
+			)
+		).toHaveValue( '2' );
+	} );
+} );
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/MiniCart.php b/plugins/woocommerce/src/Blocks/BlockTypes/MiniCart.php
index daa7d3c111..4736035981 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/MiniCart.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/MiniCart.php
@@ -601,7 +601,6 @@ class MiniCart extends AbstractBlock {
 			<div
 				data-wp-interactive="woocommerce/mini-cart"
 				data-wp-init="callbacks.setupJQueryEventBridge"
-				data-wp-init--refresh-cart-items="woocommerce::actions.refreshCartItems"
 				data-wp-on-document--wc-blocks_added_to_cart="woocommerce::actions.refreshCartItems"
 				data-wp-on-document--wc-blocks_removed_from_cart="woocommerce::actions.refreshCartItems"
 				<?php if ( 'open_drawer' === $attributes['addToCartBehaviour'] ) : ?>
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php b/plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php
index 66d518b9c1..ad4a367ecb 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php
@@ -224,7 +224,6 @@ class ProductButton extends AbstractBlock {

 		$div_directives = '
 			data-wp-interactive="woocommerce/product-button"
-			data-wp-init="actions.refreshCartItems"
 		';

 		$context_directives = wp_interactivity_data_wp_context( $context );
diff --git a/plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php b/plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php
index 19d831cf6e..e01a0f9ab1 100644
--- a/plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php
+++ b/plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php
@@ -122,7 +122,6 @@ class BlocksSharedState {
 				self::$settings_namespace,
 				array(
 					'cart'     => self::$blocks_shared_cart_state,
-					'nonce'    => wp_create_nonce( 'wc_store_api' ),
 					'noticeId' => '',
 					'restUrl'  => get_rest_url(),
 				)
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b9ac933d13..a7433ebd5c 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -3700,8 +3700,8 @@ importers:
         specifier: workspace:*
         version: link:../../../../packages/js/tracks
       '@wordpress/a11y':
-        specifier: 4.22.0
-        version: 4.22.0
+        specifier: 4.39.0
+        version: 4.39.0
       '@wordpress/autop':
         specifier: 3.16.0
         version: 3.16.0
@@ -4029,11 +4029,11 @@ importers:
         specifier: 4.45.0
         version: 4.45.0
       '@wordpress/interactivity':
-        specifier: github:woocommerce/gutenberg#interactivity-api-001&path:/packages/interactivity
-        version: https://codeload.github.com/woocommerce/gutenberg/tar.gz/96b89ddfd6344b417a6e2fcd3748be856bb55b16#path:/packages/interactivity
+        specifier: ^6.39.0
+        version: 6.39.0
       '@wordpress/interactivity-router':
-        specifier: github:woocommerce/gutenberg#interactivity-api-001&path:/packages/interactivity-router
-        version: https://codeload.github.com/woocommerce/gutenberg/tar.gz/96b89ddfd6344b417a6e2fcd3748be856bb55b16#path:/packages/interactivity-router
+        specifier: ^2.39.0
+        version: 2.39.0
       '@wordpress/is-shallow-equal':
         specifier: 4.24.0
         version: 4.24.0
@@ -10096,12 +10096,8 @@ packages:
     resolution: {integrity: sha512-wS0I78ifK1ZWdsfiiD6HlZ3sIeZ6dLY/bPw4zF1fIjva5lbCq+OTjqj0hpoDDciP+zxKYj5H7lms7BYn+YtS9Q==}
     engines: {node: '>=18.12.0', npm: '>=8.19.2'}

-  '@wordpress/a11y@4.22.0':
-    resolution: {integrity: sha512-SJfpbao8Kz2vyS7L4KADgKTMFz/U5COfSk7tmMbRVeoueWOjQWRoLP+XPfGusuTnNy+UORwSH01F7tgUdw9MTw==}
-    engines: {node: '>=18.12.0', npm: '>=8.19.2'}
-
-  '@wordpress/a11y@4.36.0':
-    resolution: {integrity: sha512-E69wsv1Ye/B3xeVVDCJO4YzHgCSVWjGPTTMe25I8HBjMyJcNvjGTSJkaWJxwRmKNapFJ7pkeVUNwmk5aJ3apWA==}
+  '@wordpress/a11y@4.39.0':
+    resolution: {integrity: sha512-uFy3FIF6MOo67tTVC2SaNyBQbFafu+DRirt2/IUQlY7w2MOiXWPaQFi3Oyy81gc8TfsooSFBlK4lrujd7O4gEw==}
     engines: {node: '>=18.12.0', npm: '>=8.19.2'}

   '@wordpress/api-fetch@5.2.7':
@@ -10676,12 +10672,8 @@ packages:
     resolution: {integrity: sha512-rE7rhOJXLh65qmngcemidbFOBAsTjpFDn7RLKTmI906gWGdPi0FESfgtPJJ2og3kCoVOjdachr9azkIZu2umtw==}
     engines: {node: '>=18.12.0', npm: '>=8.19.2'}

-  '@wordpress/dom-ready@4.23.0':
-    resolution: {integrity: sha512-Ks2MBiS519grh7BkYvGponmUztaxbDJ1xJgQPzp3e+LOgo6Z/mfBn6GfwqdXvIhS6WpCPuXCp4Wuzz0JAnvJvQ==}
-    engines: {node: '>=18.12.0', npm: '>=8.19.2'}
-
-  '@wordpress/dom-ready@4.36.0':
-    resolution: {integrity: sha512-oFhoWcqewtUJ2I3F3YWdrV30LQIPmJgDAgJ+HVt30YSHHBK5Qsb0s0//LeCagkXvXFPXFX2PVyhrq2kq67mqcg==}
+  '@wordpress/dom-ready@4.39.0':
+    resolution: {integrity: sha512-qHhRnlSK0E2GTMo1D2gOtcr9FW11HG8X8lZLkmf3N0zhjem+MP7G15jFB7wophpypL3plnBHMxiDD6qUHh9dSg==}
     engines: {node: '>=18.12.0', npm: '>=8.19.2'}

   '@wordpress/dom@2.18.0':
@@ -10981,10 +10973,6 @@ packages:
     resolution: {integrity: sha512-W82L1PdIhJPNpEb2F+0NWzrDoUqZo6NnYID7qHCexBiagq4+QS4uydM6anyFvUNrpL51CmkCNu31Xi8HjpSTGg==}
     engines: {node: '>=18.12.0', npm: '>=8.19.2'}

-  '@wordpress/hooks@4.19.1':
-    resolution: {integrity: sha512-aZOf50V6+j1s+0pq/WZ37PZxu8Dn76ww2WJRYCXtk0sAO6EG2KoX2Gc9bKv0PKwOMss5aiza8pZgIYJFuxZMOw==}
-    engines: {node: '>=18.12.0', npm: '>=8.19.2'}
-
   '@wordpress/hooks@4.20.0':
     resolution: {integrity: sha512-nn6RbAER5EitMJVr+jpOg5HDIUEEOEv6jC/P1s5C0HvsOaldBeJ80A73Gsd/NFGlUqCc7o51uoZO36wGoPjIpg==}
     engines: {node: '>=18.12.0', npm: '>=8.19.2'}
@@ -10993,12 +10981,8 @@ packages:
     resolution: {integrity: sha512-P5EH6GJyJpPHZpZC7vPcMgJP1u3u8RSqDpoLn/DC3u58FSFD5eh7wn8u2hZsT+erxVaatYRUosrfh/Qr8mwazQ==}
     engines: {node: '>=18.12.0', npm: '>=8.19.2'}

-  '@wordpress/hooks@4.23.0':
-    resolution: {integrity: sha512-dW5e8qy/02rkEHC3SRN6uoK4GOcizuLMt/E5iwI0E5EiG7PTLpKuS4riU4nYRd6BjMRpM4nP998xt3+CRLWN2A==}
-    engines: {node: '>=18.12.0', npm: '>=8.19.2'}
-
-  '@wordpress/hooks@4.36.0':
-    resolution: {integrity: sha512-9kB2lanmVrubJEqWDSHtyUx7q4ZAWGArakY/GsUdlFsnf9m+VmQLQl92uCpHWYjKzHec1hwcBhBB3Tu9aBWDtQ==}
+  '@wordpress/hooks@4.39.0':
+    resolution: {integrity: sha512-FTKdGF5jHHmC8GSO6/ATQqh1IFQeDwapRtlp7t4VaTGwZtX+uzawgq/7QDIhFi3cfg9hNsFF0CSFp/Ul3nEeUA==}
     engines: {node: '>=18.12.0', npm: '>=8.19.2'}

   '@wordpress/html-entities@3.24.0':
@@ -11068,6 +11052,11 @@ packages:
     engines: {node: '>=18.12.0', npm: '>=8.19.2'}
     hasBin: true

+  '@wordpress/i18n@6.12.0':
+    resolution: {integrity: sha512-KMleg8p/HtnoX1d/WoRDI51VTZsA4RGNUvBYn+Cc3avaeeNKROb91+viMcOc8NHuLplEzl7zH9/mrOSs9aY3rg==}
+    engines: {node: '>=18.12.0', npm: '>=8.19.2'}
+    hasBin: true
+
   '@wordpress/i18n@6.9.0':
     resolution: {integrity: sha512-ke4BPQUHmj82mwYoasotKt3Sghf0jK4vec56cWxwnzUvqq7LMy/0H7F5NzJ4CY378WS+TOdLbqmIb4sj+f7eog==}
     engines: {node: '>=18.12.0', npm: '>=8.19.2'}
@@ -11109,21 +11098,16 @@ packages:
     resolution: {integrity: sha512-Z8F+ledkfkcKDuS1c/RkM0dEWdfv2AXs6bCgey89p0atJSscf7qYbMJR9zE5rZ5aqXyFfV0DAFKJEgayNqneNQ==}
     engines: {node: '>=12'}

-  '@wordpress/interactivity-router@2.23.0':
-    resolution: {integrity: sha512-DYQPLLX/v05BAVSQtTfcKuSlVw7pwyuGO4wt6+qBw+LJivmhE/HiLyight5FYgOuqAKCa5QtcvCk/sGCqG3BVg==}
-    engines: {node: '>=18.12.0', npm: '>=8.19.2'}
-
-  '@wordpress/interactivity-router@https://codeload.github.com/woocommerce/gutenberg/tar.gz/96b89ddfd6344b417a6e2fcd3748be856bb55b16#path:/packages/interactivity-router':
-    resolution: {path: /packages/interactivity-router, tarball: https://codeload.github.com/woocommerce/gutenberg/tar.gz/96b89ddfd6344b417a6e2fcd3748be856bb55b16}
-    version: 2.23.0
+  '@wordpress/interactivity-router@2.39.0':
+    resolution: {integrity: sha512-Bf0EXQs/2tyfy1px18hIKZuPSE2pdIqm8SzmjiGwzrP0uz1bvfAeu3X3ADDN1VvN5RKbngFMv3Oe53OtTcQbNQ==}
     engines: {node: '>=18.12.0', npm: '>=8.19.2'}

   '@wordpress/interactivity@3.0.1':
     resolution: {integrity: sha512-UCZvDUJ1AB9IQHjjPHqSDDzj4Y8/BaQruzfJe5II86FruZXBHZXx1DAZb5sAe4GCOAfatbHsIFnoUAEhLDJdjg==}
     engines: {node: '>=12'}

-  '@wordpress/interactivity@6.23.0':
-    resolution: {integrity: sha512-/BfwDVjrjCczBXyXCcM6izMiWlRrgRTU/23WE555nW8xmGzpVUrp/6pSXUWYWsxNUAee/8PJ41W6BBUyhqMSsQ==}
+  '@wordpress/interactivity@6.39.0':
+    resolution: {integrity: sha512-9fjoPCOMdcwX1cGW2P4YBIK8LYkz9lhWHI8kgg4OCmBgkVuaFr+g43jjLojbD5bq2KPJYiQ1bD+hGJcgg4zPeQ==}
     engines: {node: '>=18.12.0', npm: '>=8.19.2'}

   '@wordpress/interactivity@https://codeload.github.com/woocommerce/gutenberg/tar.gz/96b89ddfd6344b417a6e2fcd3748be856bb55b16#path:/packages/interactivity':
@@ -32712,13 +32696,13 @@ snapshots:
       '@types/node': 20.17.8
     optional: true

-  '@typescript-eslint/eslint-plugin@4.33.0(@typescript-eslint/parser@4.33.0(eslint@8.55.0)(typescript@5.7.2))(eslint@8.55.0)(typescript@5.7.2)':
+  '@typescript-eslint/eslint-plugin@4.33.0(@typescript-eslint/parser@4.33.0(eslint@7.32.0)(typescript@5.7.2))(eslint@7.32.0)(typescript@5.7.2)':
     dependencies:
       '@typescript-eslint/experimental-utils': 4.33.0(eslint@7.32.0)(typescript@5.7.2)
       '@typescript-eslint/parser': 4.33.0(eslint@7.32.0)(typescript@5.7.2)
       '@typescript-eslint/scope-manager': 4.33.0
       debug: 4.4.0
-      eslint: 8.55.0
+      eslint: 7.32.0
       functional-red-black-tree: 1.0.1
       ignore: 5.3.0
       regexpp: 3.2.0
@@ -33450,16 +33434,10 @@ snapshots:
       '@wordpress/dom-ready': 4.0.1
       '@wordpress/i18n': 5.0.1

-  '@wordpress/a11y@4.22.0':
-    dependencies:
-      '@babel/runtime': 7.25.7
-      '@wordpress/dom-ready': 4.23.0
-      '@wordpress/i18n': 5.23.0
-
-  '@wordpress/a11y@4.36.0':
+  '@wordpress/a11y@4.39.0':
     dependencies:
-      '@wordpress/dom-ready': 4.36.0
-      '@wordpress/i18n': 6.9.0
+      '@wordpress/dom-ready': 4.39.0
+      '@wordpress/i18n': 6.12.0

   '@wordpress/api-fetch@5.2.7':
     dependencies:
@@ -33746,7 +33724,7 @@ snapshots:
       '@emotion/react': 11.11.1(@types/react@18.3.16)(react@18.3.1)
       '@emotion/styled': 11.11.0(@emotion/react@11.11.1(@types/react@18.3.16)(react@18.3.1))(@types/react@18.3.16)(react@18.3.1)
       '@react-spring/web': 9.7.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
-      '@wordpress/a11y': 4.22.0
+      '@wordpress/a11y': 4.39.0
       '@wordpress/api-fetch': 7.20.0
       '@wordpress/blob': 4.20.0
       '@wordpress/block-serialization-default-parser': 5.20.0
@@ -33760,7 +33738,7 @@ snapshots:
       '@wordpress/dom': 4.21.0
       '@wordpress/element': 6.21.0
       '@wordpress/escape-html': 3.20.0
-      '@wordpress/hooks': 4.23.0
+      '@wordpress/hooks': 4.39.0
       '@wordpress/html-entities': 4.21.0
       '@wordpress/i18n': 5.23.0
       '@wordpress/icons': 10.20.0(react@18.3.1)
@@ -33809,7 +33787,7 @@ snapshots:
       '@emotion/react': 11.11.1(@types/react@18.3.16)(react@18.3.1)
       '@emotion/styled': 11.11.0(@emotion/react@11.11.1(@types/react@18.3.16)(react@18.3.1))(@types/react@18.3.16)(react@18.3.1)
       '@react-spring/web': 9.7.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
-      '@wordpress/a11y': 4.22.0
+      '@wordpress/a11y': 4.39.0
       '@wordpress/api-fetch': 7.19.1
       '@wordpress/blob': 4.10.0
       '@wordpress/block-serialization-default-parser': 5.10.0
@@ -33941,8 +33919,8 @@ snapshots:
       '@wordpress/html-entities': 4.0.1
       '@wordpress/i18n': 5.0.1
       '@wordpress/icons': 10.0.2(react@18.3.1)
-      '@wordpress/interactivity': 6.23.0
-      '@wordpress/interactivity-router': 2.23.0
+      '@wordpress/interactivity': 6.39.0
+      '@wordpress/interactivity-router': 2.39.0
       '@wordpress/keyboard-shortcuts': 5.0.2(react@18.3.1)
       '@wordpress/keycodes': 4.0.1
       '@wordpress/notices': 5.0.2(react@18.3.1)
@@ -34119,7 +34097,7 @@ snapshots:
       '@wordpress/deprecated': 4.21.0
       '@wordpress/dom': 4.21.0
       '@wordpress/element': 6.21.0
-      '@wordpress/hooks': 4.23.0
+      '@wordpress/hooks': 4.39.0
       '@wordpress/html-entities': 4.21.0
       '@wordpress/i18n': 5.23.0
       '@wordpress/is-shallow-equal': 5.21.0
@@ -34149,9 +34127,9 @@ snapshots:
       '@wordpress/deprecated': 4.36.0
       '@wordpress/dom': 4.36.0
       '@wordpress/element': 6.36.0
-      '@wordpress/hooks': 4.36.0
+      '@wordpress/hooks': 4.39.0
       '@wordpress/html-entities': 4.36.0
-      '@wordpress/i18n': 6.9.0
+      '@wordpress/i18n': 6.12.0
       '@wordpress/is-shallow-equal': 5.36.0
       '@wordpress/private-apis': 1.36.0
       '@wordpress/rich-text': 7.36.0(react@18.3.1)
@@ -34635,7 +34613,7 @@ snapshots:
       '@types/gradient-parser': 0.1.3
       '@types/highlight-words-core': 1.2.1
       '@use-gesture/react': 10.3.1(react@18.3.1)
-      '@wordpress/a11y': 4.22.0
+      '@wordpress/a11y': 4.39.0
       '@wordpress/compose': 7.20.0(react@18.3.1)
       '@wordpress/date': 5.16.0
       '@wordpress/deprecated': 4.20.0
@@ -34689,14 +34667,14 @@ snapshots:
       '@types/gradient-parser': 0.1.3
       '@types/highlight-words-core': 1.2.1
       '@use-gesture/react': 10.3.1(react@18.3.1)
-      '@wordpress/a11y': 4.22.0
+      '@wordpress/a11y': 4.39.0
       '@wordpress/compose': 7.20.0(react@18.3.1)
       '@wordpress/date': 5.16.0
       '@wordpress/deprecated': 4.20.0
       '@wordpress/dom': 4.16.0
       '@wordpress/element': 6.20.0
       '@wordpress/escape-html': 3.16.0
-      '@wordpress/hooks': 4.19.1
+      '@wordpress/hooks': 4.39.0
       '@wordpress/html-entities': 4.16.0
       '@wordpress/i18n': 5.23.0
       '@wordpress/icons': 10.20.0(react@18.3.1)
@@ -34743,14 +34721,14 @@ snapshots:
       '@types/gradient-parser': 0.1.3
       '@types/highlight-words-core': 1.2.1
       '@use-gesture/react': 10.3.1(react@18.3.1)
-      '@wordpress/a11y': 4.22.0
+      '@wordpress/a11y': 4.39.0
       '@wordpress/compose': 7.20.0(react@18.3.1)
       '@wordpress/date': 5.20.0
       '@wordpress/deprecated': 4.20.0
       '@wordpress/dom': 4.20.0
       '@wordpress/element': 6.20.0
       '@wordpress/escape-html': 3.20.0
-      '@wordpress/hooks': 4.20.0
+      '@wordpress/hooks': 4.39.0
       '@wordpress/html-entities': 4.20.0
       '@wordpress/i18n': 5.23.0
       '@wordpress/icons': 10.20.0(react@18.3.1)
@@ -34797,7 +34775,7 @@ snapshots:
       '@types/gradient-parser': 0.1.3
       '@types/highlight-words-core': 1.2.1
       '@use-gesture/react': 10.3.1(react@18.3.1)
-      '@wordpress/a11y': 4.22.0
+      '@wordpress/a11y': 4.39.0
       '@wordpress/compose': 7.21.0(react@18.3.1)
       '@wordpress/date': 5.21.0
       '@wordpress/deprecated': 4.21.0
@@ -35455,11 +35433,11 @@ snapshots:
   '@wordpress/deprecated@4.21.0':
     dependencies:
       '@babel/runtime': 7.25.7
-      '@wordpress/hooks': 4.23.0
+      '@wordpress/hooks': 4.39.0

   '@wordpress/deprecated@4.36.0':
     dependencies:
-      '@wordpress/hooks': 4.36.0
+      '@wordpress/hooks': 4.39.0

   '@wordpress/dom-ready@3.27.0':
     dependencies:
@@ -35473,11 +35451,7 @@ snapshots:
     dependencies:
       '@babel/runtime': 7.25.7

-  '@wordpress/dom-ready@4.23.0':
-    dependencies:
-      '@babel/runtime': 7.25.7
-
-  '@wordpress/dom-ready@4.36.0': {}
+  '@wordpress/dom-ready@4.39.0': {}

   '@wordpress/dom@2.18.0':
     dependencies:
@@ -35875,7 +35849,7 @@ snapshots:
   '@wordpress/editor@14.8.19(@emotion/is-prop-valid@1.2.1)(@types/react-dom@18.3.0)(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
     dependencies:
       '@babel/runtime': 7.25.7
-      '@wordpress/a11y': 4.22.0
+      '@wordpress/a11y': 4.39.0
       '@wordpress/api-fetch': 7.10.0
       '@wordpress/blob': 4.10.0
       '@wordpress/block-editor': 14.5.0(@emotion/is-prop-valid@1.2.1)(@types/react-dom@18.3.0)(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -36318,7 +36292,7 @@ snapshots:
   '@wordpress/eslint-plugin@9.3.0(@babel/core@7.25.7)(eslint@7.32.0)(typescript@5.7.2)':
     dependencies:
       '@babel/eslint-parser': 7.23.3(@babel/core@7.25.7)(eslint@7.32.0)
-      '@typescript-eslint/eslint-plugin': 4.33.0(@typescript-eslint/parser@4.33.0(eslint@8.55.0)(typescript@5.7.2))(eslint@8.55.0)(typescript@5.7.2)
+      '@typescript-eslint/eslint-plugin': 4.33.0(@typescript-eslint/parser@4.33.0(eslint@7.32.0)(typescript@5.7.2))(eslint@7.32.0)(typescript@5.7.2)
       '@typescript-eslint/parser': 4.33.0(eslint@7.32.0)(typescript@5.7.2)
       '@wordpress/prettier-config': 1.4.0(wp-prettier@2.2.1-beta-1)
       cosmiconfig: 7.1.0
@@ -36353,7 +36327,7 @@ snapshots:
       '@wordpress/data': 10.0.2(patch_hash=xjmezqav3jkhcz5453svqnw2p4)(react@18.3.1)
       '@wordpress/dataviews': 4.12.0(@emotion/is-prop-valid@1.2.1)(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       '@wordpress/element': 6.21.0
-      '@wordpress/hooks': 4.23.0
+      '@wordpress/hooks': 4.39.0
       '@wordpress/html-entities': 4.21.0
       '@wordpress/i18n': 5.23.0
       '@wordpress/icons': 10.11.0
@@ -36461,10 +36435,6 @@ snapshots:
     dependencies:
       '@babel/runtime': 7.25.7

-  '@wordpress/hooks@4.19.1':
-    dependencies:
-      '@babel/runtime': 7.25.7
-
   '@wordpress/hooks@4.20.0':
     dependencies:
       '@babel/runtime': 7.25.7
@@ -36473,11 +36443,7 @@ snapshots:
     dependencies:
       '@babel/runtime': 7.25.7

-  '@wordpress/hooks@4.23.0':
-    dependencies:
-      '@babel/runtime': 7.25.7
-
-  '@wordpress/hooks@4.36.0': {}
+  '@wordpress/hooks@4.39.0': {}

   '@wordpress/html-entities@3.24.0':
     dependencies:
@@ -36554,7 +36520,7 @@ snapshots:
   '@wordpress/i18n@5.20.0':
     dependencies:
       '@babel/runtime': 7.25.7
-      '@wordpress/hooks': 4.20.0
+      '@wordpress/hooks': 4.39.0
       gettext-parser: 1.4.0
       memize: 2.1.0
       sprintf-js: 1.1.3
@@ -36572,16 +36538,24 @@ snapshots:
   '@wordpress/i18n@5.23.0':
     dependencies:
       '@babel/runtime': 7.25.7
-      '@wordpress/hooks': 4.23.0
+      '@wordpress/hooks': 4.39.0
       gettext-parser: 1.4.0
       memize: 2.1.0
       sprintf-js: 1.1.3
       tannin: 1.2.0

+  '@wordpress/i18n@6.12.0':
+    dependencies:
+      '@tannin/sprintf': 1.3.3
+      '@wordpress/hooks': 4.39.0
+      gettext-parser: 1.4.0
+      memize: 2.1.0
+      tannin: 1.2.0
+
   '@wordpress/i18n@6.9.0':
     dependencies:
       '@tannin/sprintf': 1.3.3
-      '@wordpress/hooks': 4.36.0
+      '@wordpress/hooks': 4.39.0
       gettext-parser: 1.4.0
       memize: 2.1.0
       tannin: 1.2.0
@@ -36650,14 +36624,9 @@ snapshots:
       '@wordpress/element': 5.35.0
       '@wordpress/primitives': 3.56.0

-  '@wordpress/interactivity-router@2.23.0':
-    dependencies:
-      '@wordpress/a11y': 4.22.0
-      '@wordpress/interactivity': https://codeload.github.com/woocommerce/gutenberg/tar.gz/96b89ddfd6344b417a6e2fcd3748be856bb55b16#path:/packages/interactivity
-
-  '@wordpress/interactivity-router@https://codeload.github.com/woocommerce/gutenberg/tar.gz/96b89ddfd6344b417a6e2fcd3748be856bb55b16#path:/packages/interactivity-router':
+  '@wordpress/interactivity-router@2.39.0':
     dependencies:
-      '@wordpress/a11y': 4.22.0
+      '@wordpress/a11y': 4.39.0
       '@wordpress/interactivity': https://codeload.github.com/woocommerce/gutenberg/tar.gz/96b89ddfd6344b417a6e2fcd3748be856bb55b16#path:/packages/interactivity
       es-module-lexer: 1.7.0

@@ -36670,7 +36639,7 @@ snapshots:
       - '@preact/signals-core'
       - '@preact/signals-react'

-  '@wordpress/interactivity@6.23.0':
+  '@wordpress/interactivity@6.39.0':
     dependencies:
       '@preact/signals': 1.3.1(preact@10.25.1)
       preact: 10.25.1
@@ -36733,7 +36702,7 @@ snapshots:
   '@wordpress/interface@6.9.0(@emotion/is-prop-valid@1.2.1)(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
     dependencies:
       '@babel/runtime': 7.25.7
-      '@wordpress/a11y': 4.22.0
+      '@wordpress/a11y': 4.39.0
       '@wordpress/components': 28.10.0(@emotion/is-prop-valid@1.2.1)(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       '@wordpress/compose': 7.20.0(react@18.3.1)
       '@wordpress/data': 10.0.2(patch_hash=xjmezqav3jkhcz5453svqnw2p4)(react@18.3.1)
@@ -36979,7 +36948,7 @@ snapshots:

   '@wordpress/keycodes@4.36.0':
     dependencies:
-      '@wordpress/i18n': 6.9.0
+      '@wordpress/i18n': 6.12.0

   '@wordpress/lazy-import@2.14.0':
     dependencies:
@@ -37028,14 +36997,14 @@ snapshots:
   '@wordpress/notices@5.15.1(react@18.3.1)':
     dependencies:
       '@babel/runtime': 7.25.7
-      '@wordpress/a11y': 4.22.0
+      '@wordpress/a11y': 4.39.0
       '@wordpress/data': 10.0.2(patch_hash=xjmezqav3jkhcz5453svqnw2p4)(react@18.3.1)
       react: 18.3.1

   '@wordpress/notices@5.20.0(react@18.3.1)':
     dependencies:
       '@babel/runtime': 7.25.7
-      '@wordpress/a11y': 4.22.0
+      '@wordpress/a11y': 4.39.0
       '@wordpress/data': 10.0.2(patch_hash=xjmezqav3jkhcz5453svqnw2p4)(react@18.3.1)
       react: 18.3.1

@@ -37088,7 +37057,7 @@ snapshots:
   '@wordpress/patterns@2.10.0(@emotion/is-prop-valid@1.2.1)(@types/react-dom@18.3.0)(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
     dependencies:
       '@babel/runtime': 7.25.7
-      '@wordpress/a11y': 4.22.0
+      '@wordpress/a11y': 4.39.0
       '@wordpress/block-editor': 14.5.0(@emotion/is-prop-valid@1.2.1)(@types/react-dom@18.3.0)(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       '@wordpress/blocks': 13.10.0(react@18.3.1)
       '@wordpress/components': 28.10.0(@emotion/is-prop-valid@1.2.1)(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -37097,7 +37066,7 @@ snapshots:
       '@wordpress/data': 10.0.2(patch_hash=xjmezqav3jkhcz5453svqnw2p4)(react@18.3.1)
       '@wordpress/element': 6.16.0
       '@wordpress/html-entities': 4.16.0
-      '@wordpress/i18n': 5.21.0
+      '@wordpress/i18n': 5.23.0
       '@wordpress/icons': 10.11.0
       '@wordpress/notices': 5.15.1(react@18.3.1)
       '@wordpress/private-apis': 1.16.0
@@ -37260,7 +37229,7 @@ snapshots:
   '@wordpress/preferences@4.10.0(@emotion/is-prop-valid@1.2.1)(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
     dependencies:
       '@babel/runtime': 7.25.7
-      '@wordpress/a11y': 4.22.0
+      '@wordpress/a11y': 4.39.0
       '@wordpress/components': 28.10.0(@emotion/is-prop-valid@1.2.1)(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       '@wordpress/compose': 7.20.0(react@18.3.1)
       '@wordpress/data': 10.0.2(patch_hash=xjmezqav3jkhcz5453svqnw2p4)(react@18.3.1)
@@ -37280,7 +37249,7 @@ snapshots:
   '@wordpress/preferences@4.20.0(@emotion/is-prop-valid@1.2.1)(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
     dependencies:
       '@babel/runtime': 7.25.7
-      '@wordpress/a11y': 4.22.0
+      '@wordpress/a11y': 4.39.0
       '@wordpress/components': 29.6.0(@emotion/is-prop-valid@1.2.1)(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       '@wordpress/compose': 7.21.0(react@18.3.1)
       '@wordpress/data': 10.0.2(patch_hash=xjmezqav3jkhcz5453svqnw2p4)(react@18.3.1)
@@ -37527,7 +37496,7 @@ snapshots:
       '@wordpress/core-data': 7.10.0(@emotion/is-prop-valid@1.2.1)(@types/react-dom@18.3.0)(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       '@wordpress/data': 10.0.2(patch_hash=xjmezqav3jkhcz5453svqnw2p4)(react@18.3.1)
       '@wordpress/element': 6.16.0
-      '@wordpress/i18n': 5.21.0
+      '@wordpress/i18n': 5.23.0
       '@wordpress/icons': 10.11.0
       '@wordpress/notices': 5.15.1(react@18.3.1)
       '@wordpress/private-apis': 1.16.0
@@ -37590,7 +37559,7 @@ snapshots:
   '@wordpress/rich-text@7.16.0(react@18.3.1)':
     dependencies:
       '@babel/runtime': 7.25.7
-      '@wordpress/a11y': 4.22.0
+      '@wordpress/a11y': 4.39.0
       '@wordpress/compose': 7.20.0(react@18.3.1)
       '@wordpress/data': 10.0.2(patch_hash=xjmezqav3jkhcz5453svqnw2p4)(react@18.3.1)
       '@wordpress/deprecated': 4.20.0
@@ -37604,7 +37573,7 @@ snapshots:
   '@wordpress/rich-text@7.20.0(react@18.3.1)':
     dependencies:
       '@babel/runtime': 7.25.7
-      '@wordpress/a11y': 4.22.0
+      '@wordpress/a11y': 4.39.0
       '@wordpress/compose': 7.20.0(react@18.3.1)
       '@wordpress/data': 10.0.2(patch_hash=xjmezqav3jkhcz5453svqnw2p4)(react@18.3.1)
       '@wordpress/deprecated': 4.21.0
@@ -37618,7 +37587,7 @@ snapshots:
   '@wordpress/rich-text@7.21.0(react@18.3.1)':
     dependencies:
       '@babel/runtime': 7.25.7
-      '@wordpress/a11y': 4.22.0
+      '@wordpress/a11y': 4.39.0
       '@wordpress/compose': 7.21.0(react@18.3.1)
       '@wordpress/data': 10.0.2(patch_hash=xjmezqav3jkhcz5453svqnw2p4)(react@18.3.1)
       '@wordpress/deprecated': 4.21.0
@@ -37631,13 +37600,13 @@ snapshots:

   '@wordpress/rich-text@7.36.0(react@18.3.1)':
     dependencies:
-      '@wordpress/a11y': 4.36.0
+      '@wordpress/a11y': 4.39.0
       '@wordpress/compose': 7.36.0(react@18.3.1)
       '@wordpress/data': 10.0.2(patch_hash=xjmezqav3jkhcz5453svqnw2p4)(react@18.3.1)
       '@wordpress/deprecated': 4.36.0
       '@wordpress/element': 6.36.0
       '@wordpress/escape-html': 3.36.0
-      '@wordpress/i18n': 6.9.0
+      '@wordpress/i18n': 6.12.0
       '@wordpress/keycodes': 4.36.0
       colord: 2.9.3
       memize: 2.1.0
@@ -42653,7 +42622,7 @@ snapshots:
       '@typescript-eslint/experimental-utils': 4.33.0(eslint@7.32.0)(typescript@5.7.2)
       eslint: 7.32.0
     optionalDependencies:
-      '@typescript-eslint/eslint-plugin': 4.33.0(@typescript-eslint/parser@4.33.0(eslint@8.55.0)(typescript@5.7.2))(eslint@8.55.0)(typescript@5.7.2)
+      '@typescript-eslint/eslint-plugin': 4.33.0(@typescript-eslint/parser@4.33.0(eslint@7.32.0)(typescript@5.7.2))(eslint@7.32.0)(typescript@5.7.2)
     transitivePeerDependencies:
       - supports-color
       - typescript
@@ -51926,7 +51895,7 @@ snapshots:
       neo-async: 2.6.2
     optionalDependencies:
       sass: 1.69.5
-      webpack: 5.97.1(@swc/core@1.3.100)(webpack-cli@5.1.4)
+      webpack: 5.97.1(@swc/core@1.3.100)(esbuild@0.18.20)(webpack-cli@5.1.4)

   sass@1.69.5:
     dependencies: