diff --git a/.circleci/config.yml b/.circleci/config.yml index 1d35640064..1bd2fe6a84 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -200,7 +200,7 @@ jobs: ./do download:woo-commerce-zip 9.6.2 ./do download:woo-commerce-subscriptions-zip 7.2.1 ./do download:woo-commerce-memberships-zip 1.26.5 - ./do download:automate-woo-zip 6.1.6 + ./do download:automate-woo-zip 6.1.7 - run: name: Dump tests ENV variables for acceptance tests command: | @@ -888,6 +888,146 @@ jobs: - store_artifacts: path: tests/_output + qit_malware_scan: + executor: wpcli_php_latest + steps: + - attach_workspace: + at: /home/circleci + - run: + name: 'Set up environment' + command: | + # Copy built ZIP to local directory for easier access from QIT + cp /home/circleci/mailpoet/mailpoet.zip . + # Authenticate in QIT + ./vendor/bin/qit partner:add --user="${QIT_PARTNER_USER}" --application_password="${QIT_PARTNER_SECRET}" + - run: + name: 'QIT Malware Scan' + command: ./do qa:qit-malware | tee tests/_output/qit-malware + - run: + name: 'Retrieve test results' + command: | + grep "Result Url" tests/_output/qit-malware | awk '{ print $3 }' | xargs curl -o tests/_output/report.html + when: always + - store_artifacts: + path: tests/_output + + qit_php_compatibility: + executor: wpcli_php_latest + steps: + - attach_workspace: + at: /home/circleci + - run: + name: 'Set up environment' + command: | + # Copy built ZIP to local directory for easier access from QIT + cp /home/circleci/mailpoet/mailpoet.zip . + # Authenticate in QIT + ./vendor/bin/qit partner:add --user="${QIT_PARTNER_USER}" --application_password="${QIT_PARTNER_SECRET}" + - run: + name: 'QIT PHP Compatibility Check' + command: ./do qa:qit-php-compatibility | tee tests/_output/qit-php-compatibility + - run: + name: 'Retrieve test results' + command: | + grep "Result Url" tests/_output/qit-php-compatibility | awk '{ print $3 }' | xargs curl -o tests/_output/report.html + when: always + - store_artifacts: + path: tests/_output + + qit_activation_tests: + executor: wpcli_php_latest + steps: + - attach_workspace: + at: /home/circleci + - run: + name: 'Set up environment' + command: | + # Copy built ZIP to local directory for easier access from QIT + cp /home/circleci/mailpoet/mailpoet.zip . + # Authenticate in QIT + ./vendor/bin/qit partner:add --user="${QIT_PARTNER_USER}" --application_password="${QIT_PARTNER_SECRET}" + - run: + name: 'QIT Activation Tests' + command: | + LATEST_WC_BETA=$(../.circleci/check_woocommerce_beta.sh | grep 'LATEST_BETA' | cut -d'=' -f2) + if [ -z "$LATEST_WC_BETA" ]; then + echo "No WooCommerce Beta version found. Using stable." + ./do qa:qit-activation | tee tests/_output/qit-activation + else + echo "Using WooCommerce Beta Version: $LATEST_WC_BETA" + ./do qa:qit-activation --wc=$LATEST_WC_BETA | tee tests/_output/qit-activation + fi + - run: + name: 'Retrieve test results' + command: | + grep "Result Url" tests/_output/qit-activation | awk '{ print $3 }' | xargs curl -o tests/_output/report.html + when: always + - store_artifacts: + path: tests/_output + + qit_woo_api_tests: + executor: wpcli_php_latest + steps: + - attach_workspace: + at: /home/circleci + - run: + name: 'Set up environment' + command: | + # Copy built ZIP to local directory for easier access from QIT + cp /home/circleci/mailpoet/mailpoet.zip . + # Authenticate in QIT + ./vendor/bin/qit partner:add --user="${QIT_PARTNER_USER}" --application_password="${QIT_PARTNER_SECRET}" + - run: + name: 'QIT Woo API Tests' + command: | + LATEST_WC_BETA=$(../.circleci/check_woocommerce_beta.sh | grep 'LATEST_BETA' | cut -d'=' -f2) + if [ -z "$LATEST_WC_BETA" ]; then + echo "No WooCommerce Beta version found. Using stable." + ./do qa:qit-woo-api | tee tests/_output/qit-woo-api + else + echo "Using WooCommerce Beta Version: $LATEST_WC_BETA" + ./do qa:qit-woo-api --wc=$LATEST_WC_BETA | tee tests/_output/qit-woo-api + fi + - run: + name: 'Retrieve test results' + command: | + grep "Result Url" tests/_output/qit-woo-api | awk '{ print $3 }' | xargs curl -o tests/_output/report.html + when: always + - store_artifacts: + path: tests/_output + + qit_woo_e2e_tests: + executor: wpcli_php_latest + steps: + - attach_workspace: + at: /home/circleci + - run: + name: 'Set up environment' + command: | + # Copy built ZIP to local directory for easier access from QIT + cp /home/circleci/mailpoet/mailpoet.zip . + # Authenticate in QIT + ./vendor/bin/qit partner:add --user="${QIT_PARTNER_USER}" --application_password="${QIT_PARTNER_SECRET}" + - run: + name: 'QIT Woo E2E Tests' + no_output_timeout: 1h # Woo E2E tests usually takes ~45m + command: | + LATEST_WC_BETA=$(../.circleci/check_woocommerce_beta.sh | grep 'LATEST_BETA' | cut -d'=' -f2) + if [ -z "$LATEST_WC_BETA" ]; then + echo "No WooCommerce Beta version found. Using stable." + ./do qa:qit-woo-e2e | tee tests/_output/qit-woo-e2e + else + echo "Using WooCommerce Beta Version: $LATEST_WC_BETA" + ./do qa:qit-woo-e2e --wc=$LATEST_WC_BETA | tee tests/_output/qit-woo-e2e + fi + - run: + name: 'Retrieve test results' + command: | + grep "Result Url" tests/_output/qit-woo-e2e | awk '{ print $3 }' | xargs curl -o tests/_output/report.html + when: always + - store_artifacts: + path: tests/_output + workflows: build_and_test: jobs: @@ -1209,3 +1349,43 @@ workflows: mysql_image: mysql:5.5 requires: - build_premium + + nightly_qit: + triggers: + - schedule: + cron: '0 2 * * 3' # Every Wednesday at 2am UTC + filters: + branches: + only: + - trunk + jobs: + - build: + <<: *slack-fail-post-step + - build_release_zip: + <<: *slack-fail-post-step + requires: + - build + - qit_security_scan: + <<: *slack-fail-post-step + requires: + - build_release_zip + - qit_activation_tests: + <<: *slack-fail-post-step + requires: + - build_release_zip + - qit_malware_scan: + <<: *slack-fail-post-step + requires: + - build_release_zip + - qit_php_compatibility: + <<: *slack-fail-post-step + requires: + - build_release_zip + - qit_woo_api_tests: + <<: *slack-fail-post-step + requires: + - build_release_zip + - qit_woo_e2e_tests: + <<: *slack-fail-post-step + requires: + - build_release_zip diff --git a/mailpoet/RoboFile.php b/mailpoet/RoboFile.php index 72b787e63d..25a5244502 100644 --- a/mailpoet/RoboFile.php +++ b/mailpoet/RoboFile.php @@ -815,6 +815,47 @@ class RoboFile extends \Robo\Tasks { return $this->_exec('./vendor/bin/qit run:security mailpoet --zip=mailpoet.zip --wait'); } + public function qaQitMalware() { + return $this->_exec('./vendor/bin/qit run:malware mailpoet --zip=mailpoet.zip --wait'); + } + + public function qaQitPhpCompatibility() { + return $this->_exec('./vendor/bin/qit run:phpcompatibility mailpoet --zip=mailpoet.zip --wait'); + } + + public function qaQitActivation($opts = ['wp' => 'stable', 'wc' => 'stable']) { + $command = './vendor/bin/qit run:activation mailpoet --zip=mailpoet.zip --wait'; + if ($opts['wp']) { + $command .= ' --wordpress_version=' . $opts['wp']; + } + if ($opts['wc']) { + $command .= ' --woocommerce_version=' . $opts['wc']; + } + return $this->_exec($command); + } + + public function qaQitWooApi($opts = ['wp' => 'stable', 'wc' => 'stable']) { + $command = './vendor/bin/qit run:woo-api mailpoet --zip=mailpoet.zip --wait'; + if ($opts['wp']) { + $command .= ' --wordpress_version=' . $opts['wp']; + } + if ($opts['wc']) { + $command .= ' --woocommerce_version=' . $opts['wc']; + } + return $this->_exec($command); + } + + public function qaQitWooE2e($opts = ['wp' => 'stable', 'wc' => 'stable']) { + $command = './vendor/bin/qit run:woo-e2e mailpoet --zip=mailpoet.zip --wait'; + if ($opts['wp']) { + $command .= ' --wordpress_version=' . $opts['wp']; + } + if ($opts['wc']) { + $command .= ' --woocommerce_version=' . $opts['wc']; + } + return $this->_exec($command); + } + public function svnCheckout() { $svnDir = ".mp_svn"; diff --git a/mailpoet/assets/js/src/newsletter-editor/blocks/coupon.tsx b/mailpoet/assets/js/src/newsletter-editor/blocks/coupon.tsx index b5c81f8d6a..a65f422513 100644 --- a/mailpoet/assets/js/src/newsletter-editor/blocks/coupon.tsx +++ b/mailpoet/assets/js/src/newsletter-editor/blocks/coupon.tsx @@ -19,6 +19,7 @@ Module.CouponBlockModel = base.BlockModel.extend({ return this._getDefaults( { isStandardEmail: App.getNewsletter().isStandardEmail(), + isAutomationEmail: App.getNewsletter().isAutomationEmail(), productIds: [], // selected product ids, excludedProductIds: [], productCategoryIds: [], // selected categories id @@ -33,6 +34,10 @@ Module.CouponBlockModel = base.BlockModel.extend({ minimumAmount: '', maximumAmount: '', emailRestrictions: '', + restrictToSubscriber: false, + showRestrictToSubscriber: + App.getNewsletter().isAutomationEmail() || + App.getNewsletter().isWelcomeEmail(), styles: { block: { backgroundColor: '#ffffff', diff --git a/mailpoet/assets/js/src/newsletter-editor/blocks/coupon/usage-restriction.tsx b/mailpoet/assets/js/src/newsletter-editor/blocks/coupon/usage-restriction.tsx index 650c0a2b61..fee556f060 100644 --- a/mailpoet/assets/js/src/newsletter-editor/blocks/coupon/usage-restriction.tsx +++ b/mailpoet/assets/js/src/newsletter-editor/blocks/coupon/usage-restriction.tsx @@ -31,6 +31,7 @@ type State = { productCategoryIds: Post[]; excludedProductCategoryIds: Post[]; emailRestrictions: string; + restrictToSubscriber: boolean; }; class UsageRestriction extends Component { @@ -62,6 +63,8 @@ class UsageRestriction extends Component { 'excludedProductCategoryIds', ).toJSON() as Post[], emailRestrictions: this.getValueCallback('emailRestrictions') as string, + restrictToSubscriber: + (this.getValueCallback('restrictToSubscriber') as boolean) || false, }; } @@ -262,6 +265,25 @@ class UsageRestriction extends Component { )} /> + {this.getValueCallback('showRestrictToSubscriber') && ( + + { + this.setValueCallback( + 'restrictToSubscriber', + restrictToSubscriber, + ); + this.setState({ restrictToSubscriber }); + }} + help={__( + 'Restrict coupon usage to the subscriber receiving this email.', + 'mailpoet', + )} + /> + + )} ); diff --git a/mailpoet/assets/js/src/newsletter-editor/components/content.js b/mailpoet/assets/js/src/newsletter-editor/components/content.js index 0eba43ee87..f79122ed60 100644 --- a/mailpoet/assets/js/src/newsletter-editor/components/content.js +++ b/mailpoet/assets/js/src/newsletter-editor/components/content.js @@ -35,6 +35,9 @@ Module.NewsletterModel = SuperModel.extend({ isStandardEmail: function isStandardEmail() { return this.get('type') === NewsletterType.Standard; }, + isWelcomeEmail: function isWelcomeEmail() { + return this.get('type') === NewsletterType.Welcome; + }, }); // Content block view and model handlers for different content types diff --git a/mailpoet/changelog.txt b/mailpoet/changelog.txt index 9cce33698b..e4891e62e9 100644 --- a/mailpoet/changelog.txt +++ b/mailpoet/changelog.txt @@ -1,5 +1,10 @@ == Changelog == += 5.8.0 - 2025-02-24 = +* Added: allow generating coupon code in automations for a subscriber the email is sent to; +* Changed: default MailPoet pages capability changed from post to page (one of improvements is hidden previous/next post links); +* Fixed: Prevent removing the content block from the Newsletter template in the new editor. + = 5.7.1 - 2025-02-17 = * Improved: Apply get_the_excerpt filter to MailPoets post excerpts; * Fixed: conflict with Rank Math plugin breaking "Scheduled Actions" page. diff --git a/mailpoet/lib/Newsletter/Renderer/Preprocessor.php b/mailpoet/lib/Newsletter/Renderer/Preprocessor.php index 64c78d782c..e23b68d22f 100644 --- a/mailpoet/lib/Newsletter/Renderer/Preprocessor.php +++ b/mailpoet/lib/Newsletter/Renderer/Preprocessor.php @@ -53,7 +53,7 @@ class Preprocessor { return $content; } $contentBlocks = $content['blocks']; - $contentBlocks = $this->couponPreProcessor->processCoupons($newsletter, $contentBlocks, $preview); + $contentBlocks = $this->couponPreProcessor->processCoupons($newsletter, $contentBlocks, $preview, $sendingQueue); $content['blocks'] = $this->processContainer($newsletter, $contentBlocks, $preview, $sendingQueue); return $content; } diff --git a/mailpoet/lib/Settings/Pages.php b/mailpoet/lib/Settings/Pages.php index 7de9787f2e..85780c1084 100644 --- a/mailpoet/lib/Settings/Pages.php +++ b/mailpoet/lib/Settings/Pages.php @@ -27,7 +27,18 @@ class Pages { 'can_export' => false, 'publicly_queryable' => true, 'exclude_from_search' => true, + 'capability_type' => 'page', ]); + + WPFunctions::get()->addFilter('next_post_link', [$this, 'disableNavigationLinks']); + WPFunctions::get()->addFilter('previous_post_link', [$this, 'disableNavigationLinks']); + } + + public function disableNavigationLinks($output) { + if (is_singular('mailpoet_page')) { + return ''; // Return an empty string to remove navigation links + } + return $output; } public static function createMailPoetPage($postName) { diff --git a/mailpoet/lib/WooCommerce/CouponPreProcessor.php b/mailpoet/lib/WooCommerce/CouponPreProcessor.php index 119afc61df..e5024b247d 100644 --- a/mailpoet/lib/WooCommerce/CouponPreProcessor.php +++ b/mailpoet/lib/WooCommerce/CouponPreProcessor.php @@ -3,6 +3,7 @@ namespace MailPoet\WooCommerce; use MailPoet\Entities\NewsletterEntity; +use MailPoet\Entities\SendingQueueEntity; use MailPoet\Newsletter\NewslettersRepository; use MailPoet\Newsletter\Renderer\Blocks\Coupon; use MailPoet\NewsletterProcessingException; @@ -30,12 +31,12 @@ class CouponPreProcessor { /** * @throws NewsletterProcessingException */ - public function processCoupons(NewsletterEntity $newsletter, array $blocks, bool $preview = false): array { + public function processCoupons(NewsletterEntity $newsletter, array $blocks, bool $preview = false, ?SendingQueueEntity $sendingQueue = null): array { if ($preview) { return $blocks; } - $generated = $this->ensureCouponForBlocks($blocks, $newsletter); + $generated = $this->ensureCouponForBlocks($blocks, $newsletter, $sendingQueue); $body = $newsletter->getBody(); if ($generated && $body && $this->shouldPersist($newsletter)) { @@ -54,11 +55,10 @@ class CouponPreProcessor { return $blocks; } - private function ensureCouponForBlocks(array &$blocks, NewsletterEntity $newsletter): bool { - + private function ensureCouponForBlocks(array &$blocks, NewsletterEntity $newsletter, ?SendingQueueEntity $sendingQueue): bool { foreach ($blocks as &$innerBlock) { if (isset($innerBlock['blocks']) && !empty($innerBlock['blocks'])) { - $this->ensureCouponForBlocks($innerBlock['blocks'], $newsletter); + $this->ensureCouponForBlocks($innerBlock['blocks'], $newsletter, $sendingQueue); } if (isset($innerBlock['type']) && $innerBlock['type'] === Coupon::TYPE) { if (!$this->wcHelper->isWooCommerceActive()) { @@ -66,7 +66,7 @@ class CouponPreProcessor { } if ($this->shouldGenerateCoupon($innerBlock)) { try { - $innerBlock['couponId'] = $this->addOrUpdateCoupon($innerBlock, $newsletter); + $innerBlock['couponId'] = $this->addOrUpdateCoupon($innerBlock, $newsletter, $sendingQueue); $this->generated = true; } catch (\Exception $e) { throw NewsletterProcessingException::create()->withMessage($e->getMessage())->withCode($e->getCode()); @@ -81,10 +81,11 @@ class CouponPreProcessor { /** * @param array $couponBlock * @param NewsletterEntity $newsletter + * @param SendingQueueEntity|null $sendingQueue * @return int * @throws \WC_Data_Exception|\Exception */ - private function addOrUpdateCoupon(array $couponBlock, NewsletterEntity $newsletter) { + private function addOrUpdateCoupon(array $couponBlock, NewsletterEntity $newsletter, ?SendingQueueEntity $sendingQueue) { $coupon = $this->wcHelper->createWcCoupon($couponBlock['couponId'] ?? ''); if ($this->shouldGenerateCoupon($couponBlock)) { $code = isset($couponBlock['code']) && $couponBlock['code'] !== Coupon::CODE_PLACEHOLDER ? $couponBlock['code'] : $this->generateRandomCode(); @@ -128,7 +129,24 @@ class CouponPreProcessor { $coupon->set_product_categories($this->getItemIds($couponBlock['productCategoryIds'] ?? [])); $coupon->set_excluded_product_categories($this->getItemIds($couponBlock['excludedProductCategoryIds'] ?? [])); - $coupon->set_email_restrictions(explode(',', $couponBlock['emailRestrictions'] ?? '')); + $emailRestrictions = []; + if (!empty($couponBlock['emailRestrictions'])) { + $emailRestrictions = explode(',', $couponBlock['emailRestrictions']); + } + + if (!empty($couponBlock['restrictToSubscriber']) && $sendingQueue && $sendingQueue->getTask()) { + $subscribers = $sendingQueue->getTask()->getSubscribers(); + if (is_iterable($subscribers) && count($subscribers) === 1) { // Only apply to single-subscriber sending queues + foreach ($subscribers as $taskSubscriber) { + $subscriber = $taskSubscriber->getSubscriber(); + if ($subscriber && $subscriber->getEmail()) { + $emailRestrictions[] = $subscriber->getEmail(); + } + } + } + } + + $coupon->set_email_restrictions(array_unique(array_filter($emailRestrictions))); // usage limit $coupon->set_usage_limit($couponBlock['usageLimit'] ?? 0); diff --git a/mailpoet/mailpoet.php b/mailpoet/mailpoet.php index a79c1094f8..f1ca3e559a 100644 --- a/mailpoet/mailpoet.php +++ b/mailpoet/mailpoet.php @@ -2,7 +2,7 @@ /* * Plugin Name: MailPoet - * Version: 5.7.1 + * Version: 5.8.0 * Plugin URI: https://www.mailpoet.com * Description: Create and send newsletters, post notifications and welcome emails from your WordPress. * Author: MailPoet @@ -20,7 +20,7 @@ */ $mailpoetPlugin = [ - 'version' => '5.7.1', + 'version' => '5.8.0', 'filename' => __FILE__, 'path' => dirname(__FILE__), 'autoloader' => dirname(__FILE__) . '/vendor/autoload.php', diff --git a/mailpoet/package.json b/mailpoet/package.json index 18b6785428..96e6467136 100644 --- a/mailpoet/package.json +++ b/mailpoet/package.json @@ -162,7 +162,7 @@ "js-yaml": "^4.1.0", "jsdom": "^24.1.0", "json-loader": "^0.5.7", - "mocha": "^10.4.0", + "mocha": "^10.8.2", "phplint": "^2.0.5", "postcss-cli": "^11.0.0", "postcss-scss": "^4.0.9", diff --git a/mailpoet/readme.txt b/mailpoet/readme.txt index df219339f9..e75c06c69f 100644 --- a/mailpoet/readme.txt +++ b/mailpoet/readme.txt @@ -3,7 +3,7 @@ Contributors: mailpoet, woocommerce, automattic Tags: email marketing, post notification, woocommerce emails, email automation, newsletter Requires at least: 6.6 Tested up to: 6.7 -Stable tag: 5.7.1 +Stable tag: 5.8.0 Requires PHP: 7.4 License: GPLv3 License URI: https://www.gnu.org/licenses/gpl-3.0.html @@ -222,8 +222,15 @@ Check our [Knowledge Base](https://kb.mailpoet.com) or contact us through our [s == Changelog == +<<<<<<< HEAD = 5.7.1 - 2025-02-17 = * Improved: Apply get_the_excerpt filter to MailPoets post excerpts; * Fixed: conflict with Rank Math plugin breaking "Scheduled Actions" page. +======= += 5.8.0 - 2025-02-24 = +* Added: allow generating coupon code in automations for a subscriber the email is sent to; +* Changed: default MailPoet pages capability changed from post to page (one of improvements is hidden previous/next post links); +* Fixed: Prevent removing the content block from the Newsletter template in the new editor. +>>>>>>> 5.8.0 [See the changelog for all versions.](https://github.com/mailpoet/mailpoet/blob/trunk/mailpoet/changelog.txt) diff --git a/mailpoet/tests/unit/WooCommerce/CouponPreProcessorTest.php b/mailpoet/tests/unit/WooCommerce/CouponPreProcessorTest.php index 4789e7f933..547d3f2566 100644 --- a/mailpoet/tests/unit/WooCommerce/CouponPreProcessorTest.php +++ b/mailpoet/tests/unit/WooCommerce/CouponPreProcessorTest.php @@ -5,11 +5,16 @@ namespace unit\WooCommerce; use Codeception\Stub; use Helper\WordPress; use MailPoet\Entities\NewsletterEntity; +use MailPoet\Entities\ScheduledTaskEntity; +use MailPoet\Entities\ScheduledTaskSubscriberEntity; +use MailPoet\Entities\SendingQueueEntity; +use MailPoet\Entities\SubscriberEntity; use MailPoet\Newsletter\NewslettersRepository; use MailPoet\Newsletter\Renderer\Blocks\Coupon; use MailPoet\NewsletterProcessingException; use MailPoet\WooCommerce\CouponPreProcessor; use MailPoet\WooCommerce\Helper; +use MailPoetVendor\Doctrine\Common\Collections\ArrayCollection; class CouponPreProcessorTest extends \MailPoetUnitTest { @@ -176,6 +181,68 @@ class CouponPreProcessorTest extends \MailPoetUnitTest { $processor->processCoupons($newsletter, $blocks, false); } + public function testItRestrictsCouponToSubscriber(): void { + $subscriberEmail = 'test@example.com'; + $wcCoupon = $this->createCouponMock(); + + $subscriber = $this->make(SubscriberEntity::class, [ + 'getEmail' => $subscriberEmail, + ]); + + $taskSubscriber = $this->make(ScheduledTaskSubscriberEntity::class, [ + 'getSubscriber' => $subscriber, + ]); + + $task = $this->make(ScheduledTaskEntity::class, [ + 'getSubscribers' => new ArrayCollection([$taskSubscriber]), + ]); + + $queue = $this->make(SendingQueueEntity::class, [ + 'getTask' => $task, + ]); + + $wcHelper = $this->make(Helper::class, [ + 'createWcCoupon' => $wcCoupon, + 'isWooCommerceActive' => true, + ]); + + $processor = new CouponPreProcessor( + $wcHelper, + $this->make(NewslettersRepository::class) + ); + + $newsletter = new NewsletterEntity(); + $newsletter->setType(NewsletterEntity::TYPE_AUTOMATION); + $blocks = [ + [ + 'type' => 'any', + 'blocks' => [ + [ + 'type' => Coupon::TYPE, + 'discountType' => 'percent', + 'amount' => '100', + 'restrictToSubscriber' => true, + ], + ], + ], + ]; + $newsletter->setBody(['blocks' => $blocks, 'content' => []]); + + $wcCoupon->expects($this->exactly(2)) + ->method('set_email_restrictions') + ->withConsecutive( + [[$subscriberEmail]], + [['other@example.com', $subscriberEmail]] + ); + + // Test with restrictToSubscriber enabled + $processor->processCoupons($newsletter, $blocks, false, $queue); + + // Test with additional emailRestrictions + $blocks[0]['blocks'][0]['emailRestrictions'] = 'other@example.com'; + $processor->processCoupons($newsletter, $blocks, false, $queue); + } + private function assertWCCouponReceivesCorrectValues($mockedWCCoupon, $expectedCouponId, $expiryDay) { $mockedWCCoupon->method('save')->willReturn($expectedCouponId); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a462dac039..19b096d5dd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -482,8 +482,8 @@ importers: specifier: ^0.5.7 version: 0.5.7 mocha: - specifier: ^10.4.0 - version: 10.4.0 + specifier: ^10.8.2 + version: 10.8.2 phplint: specifier: ^2.0.5 version: 2.0.5 @@ -992,7 +992,7 @@ packages: '@wordpress/primitives': 3.56.0 '@wordpress/react-i18n': 3.36.0 classnames: 2.5.1 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) react-popper: 2.3.0(@popperjs/core@2.11.8)(react-dom@18.3.1)(react@18.3.1) @@ -1168,7 +1168,7 @@ packages: '@babel/core': 7.24.7 '@babel/helper-compilation-targets': 7.24.7 '@babel/helper-plugin-utils': 7.24.8 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) lodash.debounce: 4.0.8 resolve: 1.22.8 transitivePeerDependencies: @@ -2528,7 +2528,7 @@ packages: '@babel/helper-split-export-declaration': 7.24.7 '@babel/parser': 7.24.7 '@babel/types': 7.24.7 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -2542,7 +2542,7 @@ packages: '@babel/parser': 7.26.3 '@babel/template': 7.25.9 '@babel/types': 7.26.3 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -3109,7 +3109,7 @@ packages: deprecated: Use @eslint/config-array instead dependencies: '@humanwhocodes/object-schema': 1.2.1 - debug: 4.4.0 + debug: 4.3.5(supports-color@9.3.1) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -3572,7 +3572,7 @@ packages: typescript: optional: true dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 extract-zip: 2.0.1 progress: 2.0.3 proxy-agent: 6.3.0 @@ -4651,7 +4651,7 @@ packages: '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/type-utils': 5.62.0(typescript@5.0.2) '@typescript-eslint/utils': 5.62.0(typescript@5.0.2) - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) graphemer: 1.4.0 ignore: 5.3.1 natural-compare-lite: 1.4.0 @@ -4679,7 +4679,7 @@ packages: '@typescript-eslint/type-utils': 6.21.0(eslint@8.36.0)(typescript@5.0.2) '@typescript-eslint/utils': 6.21.0(eslint@8.36.0)(typescript@5.0.2) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) eslint: 8.36.0 graphemer: 1.4.0 ignore: 5.3.1 @@ -4724,7 +4724,7 @@ packages: '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.0.2) - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) typescript: 5.0.2 transitivePeerDependencies: - supports-color @@ -4744,7 +4744,7 @@ packages: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.0.2) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) eslint: 8.36.0 typescript: 5.0.2 transitivePeerDependencies: @@ -4787,7 +4787,7 @@ packages: dependencies: '@typescript-eslint/typescript-estree': 5.56.0(typescript@5.0.2) '@typescript-eslint/utils': 5.56.0(eslint@8.36.0)(typescript@5.0.2) - debug: 4.4.0 + debug: 4.3.5(supports-color@9.3.1) eslint: 8.36.0 tsutils: 3.21.0(typescript@5.0.2) typescript: 5.0.2 @@ -4807,7 +4807,7 @@ packages: dependencies: '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.0.2) '@typescript-eslint/utils': 5.62.0(typescript@5.0.2) - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) tsutils: 3.21.0(typescript@5.0.2) typescript: 5.0.2 transitivePeerDependencies: @@ -4826,7 +4826,7 @@ packages: dependencies: '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.0.2) '@typescript-eslint/utils': 6.21.0(eslint@8.36.0)(typescript@5.0.2) - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) eslint: 8.36.0 ts-api-utils: 1.3.0(typescript@5.0.2) typescript: 5.0.2 @@ -4860,7 +4860,7 @@ packages: dependencies: '@typescript-eslint/types': 5.56.0 '@typescript-eslint/visitor-keys': 5.56.0 - debug: 4.4.0 + debug: 4.3.5(supports-color@9.3.1) globby: 11.1.0 is-glob: 4.0.3 semver: 7.6.2 @@ -4881,7 +4881,7 @@ packages: dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 semver: 7.6.2 @@ -4902,7 +4902,7 @@ packages: dependencies: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 @@ -8272,7 +8272,7 @@ packages: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} dependencies: - debug: 4.4.0 + debug: 4.3.4 transitivePeerDependencies: - supports-color dev: true @@ -8281,7 +8281,7 @@ packages: resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} engines: {node: '>= 14'} dependencies: - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true @@ -8361,8 +8361,8 @@ packages: uri-js: 4.4.1 dev: true - /ansi-colors@4.1.1: - resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} + /ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} dev: true @@ -9017,8 +9017,8 @@ packages: resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==} dev: true - /bare-events@2.5.0: - resolution: {integrity: sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==} + /bare-events@2.5.4: + resolution: {integrity: sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==} requiresBuild: true dev: true optional: true @@ -10325,7 +10325,7 @@ packages: ms: 2.1.2 dev: false - /debug@4.3.4(supports-color@8.1.1): + /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} peerDependencies: @@ -10335,7 +10335,6 @@ packages: optional: true dependencies: ms: 2.1.2 - supports-color: 8.1.1 dev: true /debug@4.3.5(supports-color@9.3.1): @@ -10351,7 +10350,7 @@ packages: supports-color: 9.3.1 dev: true - /debug@4.4.0: + /debug@4.4.0(supports-color@8.1.1): resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} engines: {node: '>=6.0'} peerDependencies: @@ -10361,6 +10360,7 @@ packages: optional: true dependencies: ms: 2.1.3 + supports-color: 8.1.1 /decamelize-keys@1.1.1: resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} @@ -10591,11 +10591,6 @@ packages: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} - /diff@5.0.0: - resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} - engines: {node: '>=0.3.1'} - dev: true - /diff@5.2.0: resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} engines: {node: '>=0.3.1'} @@ -10876,7 +10871,7 @@ packages: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} dependencies: - ansi-colors: 4.1.1 + ansi-colors: 4.1.3 strip-ansi: 6.0.1 dev: true @@ -11137,7 +11132,7 @@ packages: optional: true dependencies: '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) enhanced-resolve: 5.17.1 fast-glob: 3.3.2 get-tsconfig: 4.8.1 @@ -11399,7 +11394,7 @@ packages: '@es-joy/jsdoccomment': 0.41.0 are-docs-informative: 0.0.2 comment-parser: 1.4.1 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) escape-string-regexp: 4.0.0 eslint: 8.36.0 esquery: 1.5.0 @@ -11791,7 +11786,7 @@ packages: engines: {node: '>= 10.17.0'} hasBin: true dependencies: - debug: 4.4.0 + debug: 4.3.4 get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -11995,7 +11990,7 @@ packages: dependencies: chalk: 4.1.2 commander: 5.1.0 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true @@ -12370,7 +12365,7 @@ packages: dependencies: basic-ftp: 5.0.5 data-uri-to-buffer: 6.0.2 - debug: 4.4.0 + debug: 4.3.4 fs-extra: 11.2.0 transitivePeerDependencies: - supports-color @@ -12419,7 +12414,7 @@ packages: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 5.0.1 + minimatch: 5.1.6 once: 1.4.0 dev: true @@ -12678,7 +12673,6 @@ packages: /has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - dev: true /has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} @@ -12886,7 +12880,7 @@ packages: dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true @@ -12896,7 +12890,7 @@ packages: engines: {node: '>= 14'} dependencies: agent-base: 7.1.1 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true @@ -12936,7 +12930,7 @@ packages: engines: {node: '>= 6'} dependencies: agent-base: 6.0.2 - debug: 4.4.0 + debug: 4.3.4 transitivePeerDependencies: - supports-color dev: true @@ -12946,7 +12940,7 @@ packages: engines: {node: '>= 14'} dependencies: agent-base: 7.1.1 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true @@ -12971,7 +12965,7 @@ packages: '@babel/runtime': 7.24.7 '@tannin/sprintf': 1.2.0 '@wordpress/compose': 5.20.0(react@18.3.1) - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) events: 3.3.0 hash.js: 1.1.7 lodash: 4.17.21 @@ -13564,7 +13558,7 @@ packages: resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} engines: {node: '>=10'} dependencies: - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -15002,8 +14996,8 @@ packages: dependencies: brace-expansion: 1.1.11 - /minimatch@5.0.1: - resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} + /minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} dependencies: brace-expansion: 2.0.1 @@ -15051,30 +15045,30 @@ packages: minimist: 1.2.8 dev: true - /mocha@10.4.0: - resolution: {integrity: sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==} + /mocha@10.8.2: + resolution: {integrity: sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==} engines: {node: '>= 14.0.0'} hasBin: true dependencies: - ansi-colors: 4.1.1 + ansi-colors: 4.1.3 browser-stdout: 1.3.1 chokidar: 3.5.3 - debug: 4.3.4(supports-color@8.1.1) - diff: 5.0.0 + debug: 4.4.0(supports-color@8.1.1) + diff: 5.2.0 escape-string-regexp: 4.0.0 find-up: 5.0.0 glob: 8.1.0 he: 1.2.0 js-yaml: 4.1.0 log-symbols: 4.1.0 - minimatch: 5.0.1 + minimatch: 5.1.6 ms: 2.1.3 - serialize-javascript: 6.0.0 + serialize-javascript: 6.0.2 strip-json-comments: 3.1.1 supports-color: 8.1.1 - workerpool: 6.2.1 + workerpool: 6.5.1 yargs: 16.2.0 - yargs-parser: 20.2.4 + yargs-parser: 20.2.9 yargs-unparser: 2.0.0 dev: true @@ -15262,7 +15256,7 @@ packages: ajv-errors: 1.0.1(ajv@6.12.6) chalk: 4.1.2 cosmiconfig: 8.3.6(typescript@5.0.2) - debug: 4.3.5(supports-color@9.3.1) + debug: 4.4.0(supports-color@8.1.1) globby: 11.1.0 ignore: 5.3.1 is-plain-obj: 3.0.0 @@ -15558,7 +15552,7 @@ packages: dependencies: '@tootallnate/quickjs-emscripten': 0.23.0 agent-base: 7.1.1 - debug: 4.4.0 + debug: 4.3.4 get-uri: 6.0.3 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.5 @@ -15752,7 +15746,7 @@ packages: dependencies: '@babel/runtime': 7.24.7 crc32: 0.2.2 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) seed-random: 2.2.0 transitivePeerDependencies: - supports-color @@ -16434,7 +16428,7 @@ packages: engines: {node: '>= 14'} dependencies: agent-base: 7.1.1 - debug: 4.4.0 + debug: 4.3.4 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.5 lru-cache: 7.18.3 @@ -16483,7 +16477,7 @@ packages: engines: {node: '>=10.18.1'} dependencies: cross-fetch: 3.1.5 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 devtools-protocol: 0.0.981744 extract-zip: 2.0.1 https-proxy-agent: 5.0.1 @@ -16513,7 +16507,7 @@ packages: '@puppeteer/browsers': 1.4.6(typescript@5.0.2) chromium-bidi: 0.4.16(devtools-protocol@0.0.1147663) cross-fetch: 4.0.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 devtools-protocol: 0.0.1147663 typescript: 5.0.2 ws: 8.18.0 @@ -17617,12 +17611,6 @@ packages: tslib: 2.6.3 upper-case-first: 2.0.2 - /serialize-javascript@6.0.0: - resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} - dependencies: - randombytes: 2.1.0 - dev: true - /serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} dependencies: @@ -17766,7 +17754,7 @@ packages: resolution: {integrity: sha512-D1SaWpOW8afq1CZGWB8xTfrT3FekjQmPValrqncJMX7QFl8YwhrPTZvMCANLtgBwwdS+7zURyqxDDEmY558tTw==} dependencies: buffer: 6.0.3 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) err-code: 3.0.1 get-browser-rtc: 1.1.0 queue-microtask: 1.2.3 @@ -17878,7 +17866,7 @@ packages: base64-arraybuffer: 0.1.5 component-bind: 1.0.0 component-emitter: 1.2.1 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) engine.io-client: 3.4.4 has-binary2: 1.0.3 has-cors: 1.1.0 @@ -17917,7 +17905,7 @@ packages: engines: {node: '>= 14'} dependencies: agent-base: 7.1.1 - debug: 4.4.0 + debug: 4.3.4 socks: 2.8.3 transitivePeerDependencies: - supports-color @@ -18037,7 +18025,7 @@ packages: /spdy-transport@3.0.0: resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} dependencies: - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) detect-node: 2.1.0 hpack.js: 2.1.6 obuf: 1.1.2 @@ -18051,7 +18039,7 @@ packages: resolution: {integrity: sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==} engines: {node: '>=6.0.0'} dependencies: - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) handle-thing: 2.0.1 http-deceiver: 1.2.7 select-hose: 2.0.0 @@ -18120,7 +18108,7 @@ packages: queue-tick: 1.0.1 text-decoder: 1.1.1 optionalDependencies: - bare-events: 2.5.0 + bare-events: 2.5.4 dev: true /string-argv@0.3.1: @@ -18386,7 +18374,7 @@ packages: colord: 2.9.3 cosmiconfig: 7.1.0 css-functions-list: 3.2.2 - debug: 4.3.5(supports-color@9.3.1) + debug: 4.4.0(supports-color@8.1.1) fast-glob: 3.3.2 fastest-levenshtein: 1.0.16 file-entry-cache: 6.0.1 @@ -18498,7 +18486,6 @@ packages: engines: {node: '>=10'} dependencies: has-flag: 4.0.0 - dev: true /supports-color@9.3.1: resolution: {integrity: sha512-knBY82pjmnIzK3NifMo3RxEIRD9E0kIzV4BKcyTZ9+9kWgLMxd4PrsTSMoFQUabgRBbF8KOLRDCyKgNV+iK44Q==} @@ -19714,8 +19701,8 @@ packages: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} dev: false - /workerpool@6.2.1: - resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} + /workerpool@6.5.1: + resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==} dev: true /wp-error@1.3.0: @@ -19747,7 +19734,7 @@ packages: resolution: {integrity: sha512-NMp0YsBM40CuI5vWtHpjWOuf96rPfbpGkamlJpVwYvgenIh1ynRzqVnGfsnjofgz13T2qcKkdwJY0Y2X7z+W+w==} dependencies: '@babel/runtime': 7.24.7 - debug: 4.4.0 + debug: 4.4.0(supports-color@8.1.1) progress-event: 1.0.0 uuid: 7.0.3 wp-error: 1.3.0 @@ -19931,11 +19918,6 @@ packages: camelcase: 5.3.1 decamelize: 1.2.0 - /yargs-parser@20.2.4: - resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} - engines: {node: '>=10'} - dev: true - /yargs-parser@20.2.9: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'}