From 6c566961f648c76552286817ee0339488346ace2 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 31 Oct 2021 15:21:33 +0100 Subject: [PATCH 001/270] Switch to version-bump-prompt and remove Grunt. --- Gruntfile.js | 106 --------------------------------------------------- package.json | 13 +++---- 2 files changed, 5 insertions(+), 114 deletions(-) delete mode 100644 Gruntfile.js diff --git a/Gruntfile.js b/Gruntfile.js deleted file mode 100644 index 047844a..0000000 --- a/Gruntfile.js +++ /dev/null @@ -1,106 +0,0 @@ -module.exports = function(grunt) { - 'use strict'; - - require('load-grunt-tasks')(grunt); - - var pkg = grunt.file.readJSON('package.json'); - var config = {}; - - config.pkg = pkg; - - config['convert-svg-to-png'] = { - normal: { - options: { - size: { - w: '128px', - h: '128px' - } - }, - files: [ - { - expand: true, - src: [ - '.wordpress-org/icon.svg' - ], - dest: '.wordpress-org/128' - } - ] - }, - retina: { - options: { - size: { - w: '256px', - h: '256px' - } - }, - files: [ - { - src: [ - '.wordpress-org/icon.svg' - ], - dest: '.wordpress-org/256' - } - ] - } - }; - - config.clean = { - icons: Object.keys(config['convert-svg-to-png']).map(function(key){ - return config['convert-svg-to-png'][ key ].files[0].dest; - }) - }; - - config.rename = { - icons:{ - expand: true, - src: [ - '.wordpress-org/*/icon.png' - ], - rename: function (dest,src) { - return src.replace(/.wordpress-org\/(\d+)\/icon.png/,'.wordpress-org/icon-$1x$1.png'); - } - } - }; - - config.version = { - main: { - options: { - prefix: 'Version:[\\s]+' - }, - src: [ - '<%= pkg.name %>.php' - ] - }, - readme: { - options: { - prefix: 'Stable tag:[\\s]+' - }, - src: [ - 'readme.md' - ] - }, - pkg: { - src: [ - 'package.json' - ] - } - }; - - grunt.initConfig(config); - - grunt.registerTask('bump', function(version) { - if ( ! version ) { - grunt.fail.fatal( 'No version specified. Usage: bump:major, bump:minor, bump:patch, bump:x.y.z' ); - } - - grunt.task.run([ - 'version::' + version - ]); - }); - - grunt.registerTask('icons', [ - 'convert-svg-to-png', - 'rename:icons', - 'clean:icons' - ]); -}; diff --git a/package.json b/package.json index a29a179..e1bf155 100644 --- a/package.json +++ b/package.json @@ -7,16 +7,13 @@ "repository": "johnbillion/user-switching", "devDependencies": { "@actions/github": "^2", - "grunt": "^1", - "grunt-contrib-clean": "^2", - "grunt-convert-svg-to-png": "^1", - "grunt-rename-util": "^1", - "grunt-version": "^1", - "load-grunt-tasks": "^4", "replace-in-file": "^5", - "semver": "^7" + "semver": "^7", + "version-bump-prompt": "^6.1.0" }, "scripts": { - "grunt": "grunt" + "bump:patch": "bump patch --commit 'Version %s.' user-switching.php package.json readme.md", + "bump:minor": "bump minor --commit 'Version %s.' user-switching.php package.json readme.md", + "bump:major": "bump major --commit 'Version %s.' user-switching.php package.json readme.md" } } From 7f9bd682e18f20aa9af8e2856f03d31125284953 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 31 Oct 2021 15:33:21 +0100 Subject: [PATCH 002/270] Only run testing actions when necessary. --- .github/workflows/coding-standards.yml | 12 ++++++++++++ .github/workflows/e2e.yml | 12 ++++++++++++ .github/workflows/test.yml | 12 ++++++++++++ 3 files changed, 36 insertions(+) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 15aaa60..96d7a6d 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -5,9 +5,21 @@ on: - 'develop' - 'trunk' - 'master' + paths: + - '.github/workflows/coding-standards.yml' + - 'composer.json' + - 'phpcs.xml.dist' + - 'phpstan.neon.dist' + - 'user-switching.php' pull_request: branches: - '**' + paths: + - '.github/workflows/coding-standards.yml' + - 'composer.json' + - 'phpcs.xml.dist' + - 'phpstan.neon.dist' + - 'user-switching.php' jobs: build: diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 5d48c7c..86bfa5f 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -5,9 +5,21 @@ on: - 'develop' - 'trunk' - 'master' + paths: + - '.github/workflows/e2e.yml' + - 'behat.yml' + - 'composer.json' + - 'features/**' + - 'user-switching.php' pull_request: branches: - '**' + paths: + - '.github/workflows/e2e.yml' + - 'behat.yml' + - 'composer.json' + - 'features/**' + - 'user-switching.php' # Once weekly on Wednesdays at 06:00 UTC. schedule: - cron: '0 6 * * 3' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d5c5266..afc8477 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,9 +5,21 @@ on: - 'develop' - 'trunk' - 'master' + paths: + - '.github/workflows/test.yml' + - 'composer.json' + - 'phpunit.xml.dist' + - 'tests/**' + - 'user-switching.php' pull_request: branches: - '**' + paths: + - '.github/workflows/test.yml' + - 'composer.json' + - 'phpunit.xml.dist' + - 'tests/**' + - 'user-switching.php' # Once weekly on Wednesdays at 05:00 UTC. schedule: - cron: '0 5 * * 3' From 73be9c5dd19504435161ae53380f3467e457728a Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 31 Oct 2021 15:33:44 +0100 Subject: [PATCH 003/270] Be explicit about the PHPStan level. --- phpstan.neon.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 100b8fb..9e5f49d 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -3,7 +3,7 @@ includes: - vendor/phpstan/phpstan-phpunit/extension.neon - vendor/szepeviktor/phpstan-wordpress/extension.neon parameters: - level: max + level: 8 implicitThrows: false paths: - user-switching.php From f096e37eb0da0f1cefafe8e753f72dec0d101b13 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 31 Oct 2021 15:34:08 +0100 Subject: [PATCH 004/270] Some more specific types in docblocks. --- user-switching.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/user-switching.php b/user-switching.php index cb61451..0d1904a 100644 --- a/user-switching.php +++ b/user-switching.php @@ -886,18 +886,18 @@ public function forget_woocommerce_session() { * * Important: This does not get called for Super Admins. See filter_map_meta_cap() below. * - * @param bool[] $user_caps Array of key/value pairs where keys represent a capability name and boolean values - * represent whether the user has that capability. - * @param string[] $required_caps Array of required primitive capabilities for the requested capability. - * @param mixed[] $args { + * @param array $user_caps Array of key/value pairs where keys represent a capability name and boolean values + * represent whether the user has that capability. + * @param array $required_caps Array of required primitive capabilities for the requested capability. + * @param array $args { * Arguments that accompany the requested capability check. * * @type string $0 Requested capability. * @type int $1 Concerned user ID. * @type mixed ...$2 Optional second and further parameters. * } - * @param WP_User $user Concerned user object. - * @return bool[] Array of concerned user's capabilities. + * @param WP_User $user Concerned user object. + * @return array Array of concerned user's capabilities. */ public function filter_user_has_cap( array $user_caps, array $required_caps, array $args, WP_User $user ) { if ( 'switch_to_user' === $args[0] ) { @@ -932,10 +932,10 @@ public function filter_user_has_cap( array $user_caps, array $required_caps, arr * * It affects nothing else as Super Admins can do everything by default. * - * @param string[] $required_caps Array of required primitive capabilities for the requested capability. - * @param string $cap Capability or meta capability being checked. - * @param int $user_id Concerned user ID. - * @param mixed[] $args { + * @param array $required_caps Array of required primitive capabilities for the requested capability. + * @param string $cap Capability or meta capability being checked. + * @param int $user_id Concerned user ID. + * @param array $args { * Arguments that accompany the requested capability check. * * @type mixed ...$0 Optional second and further parameters. From 3e1b607d9e3008a44dff1cccf4963da3012c977f Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 31 Oct 2021 16:03:29 +0100 Subject: [PATCH 005/270] More cache configuration for tests. --- .github/workflows/coding-standards.yml | 2 +- .gitignore | 1 + composer.json | 2 +- phpstan.neon.dist | 2 ++ 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 96d7a6d..6120363 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -35,7 +35,7 @@ jobs: path: ~/.composer/cache key: 7.3-composer-${{ hashFiles('composer.json') }} - - name: PHPCS cache + - name: PHPCS and PHPStan cache uses: actions/cache@v1 with: path: tests/cache diff --git a/.gitignore b/.gitignore index 09fd85e..aeab66c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /build /node_modules /svn +/tests/cache /tests/wordpress /vendor diff --git a/composer.json b/composer.json index a732e71..068e1d6 100644 --- a/composer.json +++ b/composer.json @@ -51,7 +51,7 @@ "@php -r \"! file_exists( 'tests/.env' ) && copy( 'tests/.env.dist', 'tests/.env' );\"" ], "test:cs": [ - "phpcs -nps --colors --report-code --report-summary --report-width=80 ." + "phpcs -nps --colors --report-code --report-summary --report-width=80 --cache=tests/cache/phpcs.json ." ], "test:phpstan": [ "phpstan analyze" diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 9e5f49d..8919989 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -4,12 +4,14 @@ includes: - vendor/szepeviktor/phpstan-wordpress/extension.neon parameters: level: 8 + tmpDir: tests/cache implicitThrows: false paths: - user-switching.php - tests excludePaths: analyse: + - tests/cache - tests/stubs.php - tests/wordpress - tests/wp-config.php From bf8a0171426b8c5e23758cbd3c8ef206443f4367 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 31 Oct 2021 16:08:54 +0100 Subject: [PATCH 006/270] Add the tests cache directory. --- tests/cache/.gitkeep | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/cache/.gitkeep diff --git a/tests/cache/.gitkeep b/tests/cache/.gitkeep new file mode 100644 index 0000000..127395c --- /dev/null +++ b/tests/cache/.gitkeep @@ -0,0 +1 @@ +Important: This directory cannot be empty. From 8c4868c037150db9067699100dcd20e1007e8de1 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 31 Oct 2021 16:17:19 +0100 Subject: [PATCH 007/270] Some more specific types in docblocks. --- user-switching.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/user-switching.php b/user-switching.php index 0d1904a..6562983 100644 --- a/user-switching.php +++ b/user-switching.php @@ -642,9 +642,9 @@ public function filter_login_message( $message ) { /** * Adds a 'Switch To' link to each list of user actions on the Users screen. * - * @param string[] $actions Array of actions to display for this user row. - * @param WP_User $user The user object displayed in this row. - * @return string[] Array of actions to display for this user row. + * @param array $actions Array of actions to display for this user row. + * @param WP_User $user The user object displayed in this row. + * @return array Array of actions to display for this user row. */ public function filter_user_row_actions( array $actions, WP_User $user ) { $link = self::maybe_switch_url( $user ); @@ -737,8 +737,8 @@ public function action_bbpress_button() { * * @link https://core.trac.wordpress.org/ticket/23367 * - * @param string[] $args Array of removable query arguments. - * @return string[] Updated array of removable query arguments. + * @param array $args Array of removable query arguments. + * @return array Updated array of removable query arguments. */ public function filter_removable_query_args( array $args ) { return array_merge( $args, array( @@ -940,7 +940,7 @@ public function filter_user_has_cap( array $user_caps, array $required_caps, arr * * @type mixed ...$0 Optional second and further parameters. * } - * @return string[] Array of required capabilities for the requested action. + * @return array Array of required capabilities for the requested action. */ public function filter_map_meta_cap( array $required_caps, $cap, $user_id, array $args ) { if ( 'switch_to_user' === $cap ) { @@ -1124,7 +1124,7 @@ function user_switching_get_olduser_cookie() { /** * Gets the value of the auth cookie containing the list of originating users. * - * @return string[] Array of originating user authentication cookie values. Empty array if there are none. + * @return array Array of originating user authentication cookie values. Empty array if there are none. */ function user_switching_get_auth_cookie() { if ( user_switching::secure_auth_cookie() ) { From c263809bb402fafc66637364dd1343a8731f5c42 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 31 Oct 2021 16:40:09 +0100 Subject: [PATCH 008/270] Lower the timeout for all jobs to protect against eating up monthly allowance if something hangs. --- .github/workflows/coding-standards.yml | 1 + .github/workflows/deploy-assets.yml | 1 + .github/workflows/deploy-tag.yml | 1 + .github/workflows/e2e.yml | 1 + .github/workflows/test.yml | 1 + 5 files changed, 5 insertions(+) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 6120363..7340c03 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -25,6 +25,7 @@ jobs: build: name: PHP Coding Standards runs-on: ubuntu-18.04 + timeout-minutes: 10 steps: - name: Checkout repository uses: actions/checkout@v1 diff --git a/.github/workflows/deploy-assets.yml b/.github/workflows/deploy-assets.yml index ba20da8..a554c93 100644 --- a/.github/workflows/deploy-assets.yml +++ b/.github/workflows/deploy-assets.yml @@ -8,6 +8,7 @@ jobs: wordpress: name: WordPress.org runs-on: ubuntu-18.04 + timeout-minutes: 10 steps: - name: Checkout repository uses: actions/checkout@v1 diff --git a/.github/workflows/deploy-tag.yml b/.github/workflows/deploy-tag.yml index d16abb7..5f19493 100644 --- a/.github/workflows/deploy-tag.yml +++ b/.github/workflows/deploy-tag.yml @@ -7,6 +7,7 @@ jobs: wordpress: name: WordPress.org runs-on: ubuntu-18.04 + timeout-minutes: 10 steps: - name: Checkout repository uses: actions/checkout@v1 diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 86bfa5f..61985cf 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -34,6 +34,7 @@ jobs: fail-fast: false name: WP ${{ matrix.wp }} / PHP ${{ matrix.php }} runs-on: ubuntu-18.04 + timeout-minutes: 10 steps: - name: Checkout repository uses: actions/checkout@v1 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index afc8477..1859864 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,6 +34,7 @@ jobs: fail-fast: false name: WP ${{ matrix.wp }} / PHP ${{ matrix.php }} runs-on: ubuntu-18.04 + timeout-minutes: 10 steps: - name: Checkout repository uses: actions/checkout@v1 From 97390fc6a0d78492effeb88a6cfd1b77b4f2b82f Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Mon, 1 Nov 2021 15:35:05 +0100 Subject: [PATCH 009/270] Update the CI caching. --- .github/workflows/e2e.yml | 10 ++++++++-- .github/workflows/test.yml | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 61985cf..ae20f2d 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -39,10 +39,16 @@ jobs: - name: Checkout repository uses: actions/checkout@v1 + - name: Get Composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: Composer cache - uses: actions/cache@v1 + uses: actions/cache@v2 + env: + cache-name: cache-composer-dependencies with: - path: ~/.composer/cache + path: ${{ steps.composer-cache.outputs.dir }} key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} - name: Install PHP diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1859864..df8da86 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -39,10 +39,16 @@ jobs: - name: Checkout repository uses: actions/checkout@v1 + - name: Get Composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: Composer cache - uses: actions/cache@v1 + uses: actions/cache@v2 + env: + cache-name: cache-composer-dependencies with: - path: ~/.composer/cache + path: ${{ steps.composer-cache.outputs.dir }} key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} - name: Install PHP From 480ed467fa2502414d2f4093b2b4890cbddeb9bd Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Mon, 1 Nov 2021 15:35:33 +0100 Subject: [PATCH 010/270] Make these badges small again. --- readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 7787bfa..1a8c8b2 100644 --- a/readme.md +++ b/readme.md @@ -13,9 +13,9 @@ Donate link: https://github.com/sponsors/johnbillion Instant switching between user accounts in WordPress. -[![](https://img.shields.io/badge/ethical-open%20source-4baaaa.svg?style=for-the-badge)](#ethical-open-source) -[![](https://img.shields.io/wordpress/plugin/installs/user-switching?style=for-the-badge)](https://wordpress.org/plugins/user-switching/) -[![](https://img.shields.io/github/workflow/status/johnbillion/user-switching/Test/develop?style=for-the-badge)](https://github.com/johnbillion/user-switching/actions) +[![](https://img.shields.io/badge/ethical-open%20source-4baaaa.svg?style=flat-square)](#ethical-open-source) +[![](https://img.shields.io/wordpress/plugin/installs/user-switching?style=flat-square)](https://wordpress.org/plugins/user-switching/) +[![](https://img.shields.io/github/workflow/status/johnbillion/user-switching/Test/develop?style=flat-square)](https://github.com/johnbillion/user-switching/actions) ## Description From 38926c4dc67fab17315e5996453f3fe6200410cc Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Mon, 1 Nov 2021 15:36:23 +0100 Subject: [PATCH 011/270] More CI caching updates. --- .github/workflows/coding-standards.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 7340c03..e409a25 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -30,14 +30,22 @@ jobs: - name: Checkout repository uses: actions/checkout@v1 + - name: Get Composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: Composer cache - uses: actions/cache@v1 + uses: actions/cache@v2 + env: + cache-name: cache-composer-dependencies with: - path: ~/.composer/cache + path: ${{ steps.composer-cache.outputs.dir }} key: 7.3-composer-${{ hashFiles('composer.json') }} - name: PHPCS and PHPStan cache - uses: actions/cache@v1 + uses: actions/cache@v2 + env: + cache-name: cache-test-results with: path: tests/cache # This uses the hash of user-switching.php in its cache key because Actions doesn't support From d0ecff945ef432ce1d9a365ac228cdde088ffec4 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Mon, 1 Nov 2021 15:45:45 +0100 Subject: [PATCH 012/270] Update PHPStan. --- composer.json | 8 ++++---- phpstan.neon.dist | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 068e1d6..e45270d 100644 --- a/composer.json +++ b/composer.json @@ -33,12 +33,12 @@ "paulgibbs/behat-wordpress-extension": "^3.3", "php-stubs/wordpress-stubs": "^5.7", "phpcompatibility/php-compatibility": "^9", - "phpstan/phpstan": "0.12.87", - "phpstan/phpstan-deprecation-rules": "0.12.6", - "phpstan/phpstan-phpunit": "0.12.19", + "phpstan/phpstan": "1.0.0", + "phpstan/phpstan-deprecation-rules": "1.0.0", + "phpstan/phpstan-phpunit": "1.0.0", "phpunit/phpunit": "^7", "roots/wordpress": "*", - "szepeviktor/phpstan-wordpress": "^0.7.5", + "szepeviktor/phpstan-wordpress": "^1.0", "vlucas/phpdotenv": "^3", "wp-cli/core-command": "^2", "wp-cli/db-command": "^2", diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 8919989..e47f8e1 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -5,7 +5,6 @@ includes: parameters: level: 8 tmpDir: tests/cache - implicitThrows: false paths: - user-switching.php - tests From 94b1c4fc8079c927af2ca7e76fcc5a420c1439b1 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Mon, 1 Nov 2021 15:45:52 +0100 Subject: [PATCH 013/270] This is nullable. --- tests/test-plugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-plugin.php b/tests/test-plugin.php index c8f9677..dd1edc7 100644 --- a/tests/test-plugin.php +++ b/tests/test-plugin.php @@ -4,7 +4,7 @@ class TestReadme extends WP_UnitTestCase { /** - * @var array + * @var ?array */ private $readme_data; From 3ac5dd6d20a8771bcfbebac2a6017034e1039dd7 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 2 Nov 2021 00:04:51 +0100 Subject: [PATCH 014/270] Validate composer.json during CI. --- .github/workflows/coding-standards.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index e409a25..42aafbc 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -66,6 +66,9 @@ jobs: php --version composer --version + - name: Validate composer.json + run: composer validate --strict --no-check-lock + - name: Install dependencies run: | composer install --prefer-dist From 93977963779e279f1a25136034065b466cc79319 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 9 Nov 2021 16:38:22 +0000 Subject: [PATCH 015/270] Whitespace. --- features/bootstrap/UserSwitchingContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/bootstrap/UserSwitchingContext.php b/features/bootstrap/UserSwitchingContext.php index b88e3d0..c5bf86d 100644 --- a/features/bootstrap/UserSwitchingContext.php +++ b/features/bootstrap/UserSwitchingContext.php @@ -12,7 +12,7 @@ * Defines application features from the specific context. */ class UserSwitchingContext extends WordPressContext { - use UserContext; + use UserContext; /** * Switch to the specified user From 76bd8605e6e35d5e8f658373a2a51162c0716c7d Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Mon, 1 Nov 2021 16:26:25 +0100 Subject: [PATCH 016/270] Switch to johnbillion/wordhat. --- behat.yml | 10 +++++----- bin/test.sh | 2 +- composer.json | 2 +- features/bootstrap/UserSwitchingContext.php | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/behat.yml b/behat.yml index 8bc895d..d8b3887 100644 --- a/behat.yml +++ b/behat.yml @@ -3,11 +3,11 @@ default: default: contexts: - UserSwitchingContext - - PaulGibbs\WordpressBehatExtension\Context\WordpressContext + - WordHat\Extension\Context\WordpressContext - Behat\MinkExtension\Context\MinkContext - - PaulGibbs\WordpressBehatExtension\Context\DashboardContext - - PaulGibbs\WordpressBehatExtension\Context\SiteContext - - PaulGibbs\WordpressBehatExtension\Context\UserContext + - WordHat\Extension\Context\DashboardContext + - WordHat\Extension\Context\SiteContext + - WordHat\Extension\Context\UserContext - FailAid\Context\FailureContext extensions: @@ -21,7 +21,7 @@ default: guzzle_parameters: verify: false # Allow self-signed SSL certificates - PaulGibbs\WordpressBehatExtension: + WordHat\Extension: default_driver: wpphp users: - diff --git a/bin/test.sh b/bin/test.sh index 14bb611..8903974 100755 --- a/bin/test.sh +++ b/bin/test.sh @@ -23,7 +23,7 @@ $WP language core install it_IT $WP language plugin install user-switching it_IT # Run the functional tests: -BEHAT_PARAMS='{"extensions" : {"PaulGibbs\\WordpressBehatExtension" : {"path" : "'$WP_CORE_DIR'"}}}' \ +BEHAT_PARAMS='{"extensions" : {"WordHat\\Extension" : {"path" : "'$WP_CORE_DIR'"}}}' \ ./vendor/bin/behat --colors "$1" # Stop the PHP web server: diff --git a/composer.json b/composer.json index e45270d..21a41ce 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,7 @@ "dealerdirect/phpcodesniffer-composer-installer": "0.7.0", "genesis/behat-fail-aid": "^2.0", "johnbillion/php-docs-standards": "^2", - "paulgibbs/behat-wordpress-extension": "^3.3", + "johnbillion/wordhat": "dev-develop", "php-stubs/wordpress-stubs": "^5.7", "phpcompatibility/php-compatibility": "^9", "phpstan/phpstan": "1.0.0", diff --git a/features/bootstrap/UserSwitchingContext.php b/features/bootstrap/UserSwitchingContext.php index b88e3d0..5915509 100644 --- a/features/bootstrap/UserSwitchingContext.php +++ b/features/bootstrap/UserSwitchingContext.php @@ -4,8 +4,8 @@ use Behat\Mink\Exception\ElementHtmlException; use Behat\Mink\Exception\ElementTextException; use Behat\Mink\Exception\ExpectationException; -use PaulGibbs\WordpressBehatExtension\Context\RawWordpressContext as WordPressContext; -use PaulGibbs\WordpressBehatExtension\Context\Traits\UserAwareContextTrait as UserContext; +use WordHat\Extension\Context\RawWordpressContext as WordPressContext; +use WordHat\Extension\Context\Traits\UserAwareContextTrait as UserContext; use PHPUnit\Framework\Assert; /** From a97f7c4efe9d5a0b08586e141d90a84608f4fb04 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 9 Nov 2021 16:47:00 +0000 Subject: [PATCH 017/270] Use the latest PHP docs standards package. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index e45270d..1161af4 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,7 @@ "behat/mink-goutte-driver": "^1.2", "dealerdirect/phpcodesniffer-composer-installer": "0.7.0", "genesis/behat-fail-aid": "^2.0", - "johnbillion/php-docs-standards": "^2", + "johnbillion/php-docs-standards": "*", "paulgibbs/behat-wordpress-extension": "^3.3", "php-stubs/wordpress-stubs": "^5.7", "phpcompatibility/php-compatibility": "^9", From c93fd0cc6444e4b985726b5321c07a7f5a1e8085 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 9 Nov 2021 17:03:42 +0000 Subject: [PATCH 018/270] More whitespace. --- features/bootstrap/UserSwitchingContext.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/features/bootstrap/UserSwitchingContext.php b/features/bootstrap/UserSwitchingContext.php index 55ffeee..21f20e0 100644 --- a/features/bootstrap/UserSwitchingContext.php +++ b/features/bootstrap/UserSwitchingContext.php @@ -131,8 +131,8 @@ public function logged_out() { * @Then /^the page language should be "(?P[^"]+)"$/ * * @throws ElementHtmlException If the language is incorrect. - */ - public function thePageLanguageShouldBe( $lang ) { + */ + public function thePageLanguageShouldBe( $lang ) { $this->theElementLanguageShouldBe( 'html', $lang ); } @@ -145,8 +145,8 @@ public function thePageLanguageShouldBe( $lang ) { * @Then /^the "(?P[^"]+)" element language should be "(?P[^"]+)"$/ * * @throws ElementHtmlException If the language is incorrect. - */ - public function theElementLanguageShouldBe( $selector, $lang ) { + */ + public function theElementLanguageShouldBe( $selector, $lang ) { $browser = $this->getSession(); $element = $browser->getPage()->find( 'css', $selector ); @@ -170,5 +170,5 @@ public function theElementLanguageShouldBe( $selector, $lang ) { $element ); } - } + } } From 54f94f6d2502ae2dd3187316ff6084f76edb642a Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 9 Nov 2021 20:48:27 +0000 Subject: [PATCH 019/270] Really need non-zero exit codes to cause the job to fail. --- bin/test.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bin/test.sh b/bin/test.sh index 8903974..edc9175 100755 --- a/bin/test.sh +++ b/bin/test.sh @@ -1,5 +1,9 @@ #!/usr/bin/env bash +# -e Exit immediately if a pipeline returns a non-zero status +# -x Print a trace of commands and their arguments after they are expanded and before they are executed +set -ex + # Specify the directory where the WordPress installation lives: WP_CORE_DIR="${PWD}/tests/wordpress" @@ -24,7 +28,7 @@ $WP language plugin install user-switching it_IT # Run the functional tests: BEHAT_PARAMS='{"extensions" : {"WordHat\\Extension" : {"path" : "'$WP_CORE_DIR'"}}}' \ - ./vendor/bin/behat --colors "$1" + ./vendor/bin/behat --colors --strict "$1" # Stop the PHP web server: kill $! From 74080c4c401920484e9b27a6a860ab7e1d4a022e Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 9 Nov 2021 20:48:52 +0000 Subject: [PATCH 020/270] Enable Xdebug in dev mode so we get full stack traces for errors. --- .github/workflows/e2e.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index ae20f2d..3117c38 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -55,8 +55,8 @@ jobs: uses: shivammathur/setup-php@2.7.0 with: php-version: ${{ matrix.php }} - extensions: mysqli, xmlwriter - coverage: none + extensions: mysqli, xmlwriter, xdebug + ini-values: xdebug.mode="develop" env: fail-fast: true From 08f81a7ef7facb09e8534c74998365a1850ee59c Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 9 Nov 2021 23:52:31 +0000 Subject: [PATCH 021/270] Adjust the exit code options. --- bin/test.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/test.sh b/bin/test.sh index edc9175..de4e525 100755 --- a/bin/test.sh +++ b/bin/test.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash -# -e Exit immediately if a pipeline returns a non-zero status -# -x Print a trace of commands and their arguments after they are expanded and before they are executed -set -ex +# -e Exit immediately if a pipeline returns a non-zero status +# -o pipefail Produce a failure return code if any command errors +set -eo pipefail # Specify the directory where the WordPress installation lives: WP_CORE_DIR="${PWD}/tests/wordpress" From 3ec36946c47706a7298f8db667f69b03ffb15460 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 10 Nov 2021 00:21:38 +0000 Subject: [PATCH 022/270] Fix the exiting. --- bin/test.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/test.sh b/bin/test.sh index de4e525..b75672d 100755 --- a/bin/test.sh +++ b/bin/test.sh @@ -28,7 +28,8 @@ $WP language plugin install user-switching it_IT # Run the functional tests: BEHAT_PARAMS='{"extensions" : {"WordHat\\Extension" : {"path" : "'$WP_CORE_DIR'"}}}' \ - ./vendor/bin/behat --colors --strict "$1" + ./vendor/bin/behat --colors --strict "$1" \ + || BEHAT_EXIT_CODE=$? && kill $! && exit $BEHAT_EXIT_CODE # Stop the PHP web server: kill $! From c7c8369d4edd0213946a4ba9dd984f620a5098b4 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 10 Nov 2021 00:23:58 +0000 Subject: [PATCH 023/270] Run the e2e tests when the e2e test runner changes. --- .github/workflows/e2e.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 3117c38..c44e11b 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -8,6 +8,7 @@ on: paths: - '.github/workflows/e2e.yml' - 'behat.yml' + - 'bin/test.sh' - 'composer.json' - 'features/**' - 'user-switching.php' @@ -17,6 +18,7 @@ on: paths: - '.github/workflows/e2e.yml' - 'behat.yml' + - 'bin/test.sh' - 'composer.json' - 'features/**' - 'user-switching.php' From d784c28c16ae35979e7958d6defeb928aa9d1dcd Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 10 Nov 2021 00:29:07 +0000 Subject: [PATCH 024/270] Only run the functional tests on PHP 7.4 for now. --- .github/workflows/e2e.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index c44e11b..3abb133 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -31,7 +31,7 @@ jobs: build: strategy: matrix: - php: ['7.3','8.0'] + php: ['7.4'] wp: ['*', 'dev-nightly'] fail-fast: false name: WP ${{ matrix.wp }} / PHP ${{ matrix.php }} @@ -72,8 +72,8 @@ jobs: - name: Install dependencies run: | sudo systemctl start mysql.service - composer install --prefer-dist --ignore-platform-reqs - composer require --dev --update-with-dependencies --prefer-dist --ignore-platform-reqs roots/wordpress="${{ matrix.wp }} || *" + composer install --prefer-dist + composer require --dev --update-with-dependencies --prefer-dist roots/wordpress="${{ matrix.wp }} || *" - name: Run the tests run: composer test:ft From 2fdab9caef96c9e76a0ae5ad6a742dd5a1c0c363 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 16 Nov 2021 15:39:27 +0000 Subject: [PATCH 025/270] Match the wp-phpunit version with core. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index c4adb3b..26fd3eb 100644 --- a/composer.json +++ b/composer.json @@ -44,7 +44,7 @@ "wp-cli/db-command": "^2", "wp-cli/language-command": "^2", "wp-coding-standards/wpcs": "^2", - "wp-phpunit/wp-phpunit": "*" + "wp-phpunit/wp-phpunit": "^5.7" }, "scripts": { "post-update-cmd": [ From fea360b9c703681e6a05b45fb9f09c63d434e591 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 16 Nov 2021 15:39:46 +0000 Subject: [PATCH 026/270] Add phpunit-polyfills. --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 26fd3eb..fb1411c 100644 --- a/composer.json +++ b/composer.json @@ -44,7 +44,8 @@ "wp-cli/db-command": "^2", "wp-cli/language-command": "^2", "wp-coding-standards/wpcs": "^2", - "wp-phpunit/wp-phpunit": "^5.7" + "wp-phpunit/wp-phpunit": "^5.7", + "yoast/phpunit-polyfills": "^1.0" }, "scripts": { "post-update-cmd": [ From 455e15461628cbcbcf0c480f3f0a34eab418e822 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 16 Nov 2021 15:41:52 +0000 Subject: [PATCH 027/270] Switch back to using the latest stable version for everything WP. --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index fb1411c..187ff71 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "genesis/behat-fail-aid": "^2.0", "johnbillion/php-docs-standards": "*", "johnbillion/wordhat": "dev-develop", - "php-stubs/wordpress-stubs": "^5.7", + "php-stubs/wordpress-stubs": "*", "phpcompatibility/php-compatibility": "^9", "phpstan/phpstan": "1.0.0", "phpstan/phpstan-deprecation-rules": "1.0.0", @@ -44,7 +44,7 @@ "wp-cli/db-command": "^2", "wp-cli/language-command": "^2", "wp-coding-standards/wpcs": "^2", - "wp-phpunit/wp-phpunit": "^5.7", + "wp-phpunit/wp-phpunit": "*", "yoast/phpunit-polyfills": "^1.0" }, "scripts": { From 6294d56e0e0fa1435a2140e9d1d02ca4ace0bbef Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 16 Nov 2021 15:41:57 +0000 Subject: [PATCH 028/270] This isn't needed. --- behat.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/behat.yml b/behat.yml index d8b3887..cc9e1c8 100644 --- a/behat.yml +++ b/behat.yml @@ -13,7 +13,6 @@ default: extensions: Behat\MinkExtension: base_url: 'http://localhost:8000' - browser_name: chrome default_session: default sessions: default: From a4065627f865bf58f0ae54b3de61887e87f29040 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 16 Nov 2021 15:52:59 +0000 Subject: [PATCH 029/270] Relax the PHPStan version constraints. --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 187ff71..6e8530f 100644 --- a/composer.json +++ b/composer.json @@ -33,9 +33,9 @@ "johnbillion/wordhat": "dev-develop", "php-stubs/wordpress-stubs": "*", "phpcompatibility/php-compatibility": "^9", - "phpstan/phpstan": "1.0.0", - "phpstan/phpstan-deprecation-rules": "1.0.0", - "phpstan/phpstan-phpunit": "1.0.0", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", "phpunit/phpunit": "^7", "roots/wordpress": "*", "szepeviktor/phpstan-wordpress": "^1.0", From 4aff2a0c83a06c9f43a3003e0d458de3ce02ccff Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 16 Nov 2021 12:35:42 +0000 Subject: [PATCH 030/270] A private method cannot be overridden so making it final is redundant. --- user-switching.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user-switching.php b/user-switching.php index 6562983..a00d0c0 100644 --- a/user-switching.php +++ b/user-switching.php @@ -969,7 +969,7 @@ public static function get_instance() { /** * Private class constructor. Use `get_instance()` to get the instance. */ - final private function __construct() {} + private function __construct() {} } From 8668ce13f2ec96ad30dbd5f609c5efc4b3603140 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 16 Nov 2021 18:38:39 +0000 Subject: [PATCH 031/270] This is still an issue: https://github.com/redhat-developer/vscode-yaml/issues/397 --- .github/workflows/coding-standards.yml | 2 ++ .github/workflows/deploy-assets.yml | 2 ++ .github/workflows/deploy-tag.yml | 2 ++ .github/workflows/e2e.yml | 2 ++ .github/workflows/test.yml | 2 ++ 5 files changed, 10 insertions(+) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 42aafbc..0dc9c31 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow + name: Coding Standards on: push: diff --git a/.github/workflows/deploy-assets.yml b/.github/workflows/deploy-assets.yml index a554c93..01adf99 100644 --- a/.github/workflows/deploy-assets.yml +++ b/.github/workflows/deploy-assets.yml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow + name: Deploy Assets on: push: diff --git a/.github/workflows/deploy-tag.yml b/.github/workflows/deploy-tag.yml index 5f19493..c858404 100644 --- a/.github/workflows/deploy-tag.yml +++ b/.github/workflows/deploy-tag.yml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow + name: Deploy Tag on: release: diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 3abb133..d7e1fa4 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow + name: Functional Tests on: push: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index df8da86..6a68a57 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow + name: Unit Tests on: push: From 1ebd13c70392991bd9db7a0bc3ddb486188ed9b0 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 17 Nov 2021 20:57:19 +0000 Subject: [PATCH 032/270] More badge updates. --- CONTRIBUTING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3a64275..14868be 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ -[![Build Status](https://img.shields.io/github/workflow/status/johnbillion/user-switching/Test/develop?style=for-the-badge)](https://github.com/johnbillion/user-switching/actions) -[![](https://img.shields.io/badge/contributor-code%20of%20conduct-5e0d73.svg?style=for-the-badge)](https://github.com/johnbillion/user-switching/blob/develop/CODE_OF_CONDUCT.md) -[![](https://img.shields.io/badge/ethical-open%20source-4baaaa.svg?style=for-the-badge)](#ethical-open-source) +[![Build Status](https://img.shields.io/github/workflow/status/johnbillion/user-switching/Test/develop?style=flat-square)](https://github.com/johnbillion/user-switching/actions) +[![](https://img.shields.io/badge/contributor-code%20of%20conduct-5e0d73.svg?style=flat-square)](https://github.com/johnbillion/user-switching/blob/develop/CODE_OF_CONDUCT.md) +[![](https://img.shields.io/badge/ethical-open%20source-4baaaa.svg?style=flat-square)](#ethical-open-source) # Contributing to User Switching From 496db56479259b8bc2c346db083791e59f6a5f9c Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 17 Nov 2021 20:57:36 +0000 Subject: [PATCH 033/270] Bug fixes and performance improvements. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 6e8530f..69c7db7 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ "php": ">=5.3", "composer/installers": "^1" }, - "require-dev" : { + "require-dev": { "behat/mink-goutte-driver": "^1.2", "dealerdirect/phpcodesniffer-composer-installer": "0.7.0", "genesis/behat-fail-aid": "^2.0", From 8cf1bcaabcafa987b4eb0943f991e013b9e5f6de Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 20 Nov 2021 22:30:26 +0000 Subject: [PATCH 034/270] Don't need this, it's from the mysql container. --- .github/workflows/e2e.yml | 1 - .github/workflows/test.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index d7e1fa4..dcc6106 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -80,5 +80,4 @@ jobs: - name: Run the tests run: composer test:ft env: - MYSQL_DATABASE: wordpress WP_TESTS_DB_PASS: root diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6a68a57..02dda63 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -78,5 +78,4 @@ jobs: - name: Run the tests run: composer test:ut env: - MYSQL_DATABASE: wordpress WP_TESTS_DB_PASS: root From 748661c9850292eca3db94e843f15d1d37488a04 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 18:45:57 +0100 Subject: [PATCH 035/270] Add an editor config file. --- .editorconfig | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..5d36dbe --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = tab +indent_size = 4 +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.yml] +indent_style = space +indent_size = 2 From 565e11cd1fafb66e5c6b8a763eb0d2082f3af9fc Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 18:46:01 +0100 Subject: [PATCH 036/270] Tabs! --- phpstan.neon.dist | 62 +++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index e47f8e1..8d0d8f9 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,33 +1,33 @@ includes: - - vendor/phpstan/phpstan-deprecation-rules/rules.neon - - vendor/phpstan/phpstan-phpunit/extension.neon - - vendor/szepeviktor/phpstan-wordpress/extension.neon + - vendor/phpstan/phpstan-deprecation-rules/rules.neon + - vendor/phpstan/phpstan-phpunit/extension.neon + - vendor/szepeviktor/phpstan-wordpress/extension.neon parameters: - level: 8 - tmpDir: tests/cache - paths: - - user-switching.php - - tests - excludePaths: - analyse: - - tests/cache - - tests/stubs.php - - tests/wordpress - - tests/wp-config.php - - tests/wp-tests-config.php - scanDirectories: - - tests - - vendor/johnbillion/php-docs-standards - - vendor/wp-phpunit/wp-phpunit/includes - scanFiles: - - user-switching.php - bootstrapFiles: - - tests/stubs.php - ignoreErrors: - # Uses func_get_args() - - '#^Function apply_filters invoked with [34567] parameters, 2 required\.$#' - # Covers the breaks after exits in user_switching::action_init() - - - message: '#^Unreachable statement#' - path: user-switching.php - count: 3 + level: 8 + tmpDir: tests/cache + paths: + - user-switching.php + - tests + excludePaths: + analyse: + - tests/cache + - tests/stubs.php + - tests/wordpress + - tests/wp-config.php + - tests/wp-tests-config.php + scanDirectories: + - tests + - vendor/johnbillion/php-docs-standards + - vendor/wp-phpunit/wp-phpunit/includes + scanFiles: + - user-switching.php + bootstrapFiles: + - tests/stubs.php + ignoreErrors: + # Uses func_get_args() + - '#^Function apply_filters invoked with [34567] parameters, 2 required\.$#' + # Covers the breaks after exits in user_switching::action_init() + - + message: '#^Unreachable statement#' + path: user-switching.php + count: 3 From a4e06372208f21a8d06487f9446e2987cb8cbf77 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 18:48:52 +0100 Subject: [PATCH 037/270] Trust the known Composer plugins. --- composer.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 69c7db7..7678cb7 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,13 @@ "source": "https://github.com/johnbillion/user-switching" }, "config": { - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "composer/installers": true, + "composer/package-versions-deprecated": true, + "dealerdirect/phpcodesniffer-composer-installer": true, + "roots/wordpress-core-installer": true + } }, "extra": { "wordpress-install-dir": "tests/wordpress" From a083fcf3c5f75f73ca180ef2d50b7d4504643319 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 18:49:20 +0100 Subject: [PATCH 038/270] Formatting. --- composer.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index 7678cb7..15adde2 100644 --- a/composer.json +++ b/composer.json @@ -1,12 +1,12 @@ { - "name" : "johnbillion/user-switching", + "name": "johnbillion/user-switching", "description": "Instant switching between user accounts in WordPress.", - "homepage" : "https://github.com/johnbillion/user-switching", - "type" : "wordpress-plugin", - "license" : "GPL-2.0-or-later", - "authors" : [ + "homepage": "https://github.com/johnbillion/user-switching", + "type": "wordpress-plugin", + "license": "GPL-2.0-or-later", + "authors": [ { - "name" : "John Blackbourn", + "name": "John Blackbourn", "homepage": "https://johnblackbourn.com/" } ], From 3f85945b96c4d3a39caeab19af5aef793c9ce281 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 18:50:07 +0100 Subject: [PATCH 039/270] More tabs. --- package.json | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index e1bf155..0733c2c 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,19 @@ { - "name": "user-switching", - "version": "1.5.8", - "description": "Instant switching between user accounts in WordPress.", - "license": "GPL-2.0-or-later", - "author": "John Blackbourn", - "repository": "johnbillion/user-switching", - "devDependencies": { - "@actions/github": "^2", - "replace-in-file": "^5", - "semver": "^7", - "version-bump-prompt": "^6.1.0" - }, - "scripts": { - "bump:patch": "bump patch --commit 'Version %s.' user-switching.php package.json readme.md", - "bump:minor": "bump minor --commit 'Version %s.' user-switching.php package.json readme.md", - "bump:major": "bump major --commit 'Version %s.' user-switching.php package.json readme.md" - } + "name": "user-switching", + "version": "1.5.8", + "description": "Instant switching between user accounts in WordPress.", + "license": "GPL-2.0-or-later", + "author": "John Blackbourn", + "repository": "johnbillion/user-switching", + "devDependencies": { + "@actions/github": "^2", + "replace-in-file": "^5", + "semver": "^7", + "version-bump-prompt": "^6.1.0" + }, + "scripts": { + "bump:patch": "bump patch --commit 'Version %s.' user-switching.php package.json readme.md", + "bump:minor": "bump minor --commit 'Version %s.' user-switching.php package.json readme.md", + "bump:major": "bump major --commit 'Version %s.' user-switching.php package.json readme.md" + } } From c671f4f56956c2e2667678a63392a2a43fa5a61b Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 18:50:25 +0100 Subject: [PATCH 040/270] Happy new year. --- user-switching.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user-switching.php b/user-switching.php index a00d0c0..153f244 100644 --- a/user-switching.php +++ b/user-switching.php @@ -5,7 +5,7 @@ * @package user-switching * @link https://github.com/johnbillion/user-switching * @author John Blackbourn - * @copyright 2009-2021 John Blackbourn + * @copyright 2009-2022 John Blackbourn * @license GPL v2 or later * * Plugin Name: User Switching From b39e69be1871494fd5716802907b5c4a8649a31a Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 19:15:38 +0100 Subject: [PATCH 041/270] Switch to WPBrowser for the unit tests and add basic configuration. --- codeception.dist.yml | 12 ++++++++++++ composer.json | 12 +++++++++--- tests/.env.dist | 2 +- tests/_support/WpunitTester.php | 22 ++++++++++++++++++++++ tests/wpunit.suite.yml | 17 +++++++++++++++++ 5 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 codeception.dist.yml create mode 100644 tests/_support/WpunitTester.php create mode 100644 tests/wpunit.suite.yml diff --git a/codeception.dist.yml b/codeception.dist.yml new file mode 100644 index 0000000..99ea77e --- /dev/null +++ b/codeception.dist.yml @@ -0,0 +1,12 @@ +paths: + tests: tests + output: tests/_output + data: tests/_data + support: tests/_support + envs: tests/_envs +actor_suffix: Tester +extensions: + enabled: + - Codeception\Extension\RunFailed +params: + - tests/.env diff --git a/composer.json b/composer.json index 15adde2..ca47d94 100644 --- a/composer.json +++ b/composer.json @@ -37,6 +37,14 @@ "genesis/behat-fail-aid": "^2.0", "johnbillion/php-docs-standards": "*", "johnbillion/wordhat": "dev-develop", + "codeception/module-asserts": "^1.0", + "codeception/module-cli": "^1.0", + "codeception/module-db": "^1.0", + "codeception/module-filesystem": "^1.0", + "codeception/module-phpbrowser": "^1.0", + "codeception/module-webdriver": "^1.0", + "codeception/util-universalframework": "^1.0", + "lucatume/wp-browser": "^3.0", "php-stubs/wordpress-stubs": "*", "phpcompatibility/php-compatibility": "^9", "phpstan/phpstan": "^1.0", @@ -49,9 +57,7 @@ "wp-cli/core-command": "^2", "wp-cli/db-command": "^2", "wp-cli/language-command": "^2", - "wp-coding-standards/wpcs": "^2", - "wp-phpunit/wp-phpunit": "*", - "yoast/phpunit-polyfills": "^1.0" + "wp-coding-standards/wpcs": "^2" }, "scripts": { "post-update-cmd": [ diff --git a/tests/.env.dist b/tests/.env.dist index 0c521df..cabbd93 100644 --- a/tests/.env.dist +++ b/tests/.env.dist @@ -1,4 +1,4 @@ WP_TESTS_DB_NAME="wordpress_test" WP_TESTS_DB_USER="root" -WP_TESTS_DB_PASS="" +WP_TESTS_DB_PASS="root" WP_TESTS_DB_HOST="localhost" diff --git a/tests/_support/WpunitTester.php b/tests/_support/WpunitTester.php new file mode 100644 index 0000000..ede0a7e --- /dev/null +++ b/tests/_support/WpunitTester.php @@ -0,0 +1,22 @@ + Date: Tue, 4 Jan 2022 20:00:09 +0100 Subject: [PATCH 042/270] More test config. --- .gitignore | 2 ++ composer.json | 6 ++++++ tests/_data/.gitkeep | 0 tests/_output/.gitkeep | 0 tests/wpunit.suite.yml | 1 + 5 files changed, 9 insertions(+) create mode 100644 tests/_data/.gitkeep create mode 100644 tests/_output/.gitkeep diff --git a/.gitignore b/.gitignore index aeab66c..86b3a97 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ /build /node_modules /svn +/tests/_output/ +/tests/_support/_generated /tests/cache /tests/wordpress /vendor diff --git a/composer.json b/composer.json index ca47d94..4584d0e 100644 --- a/composer.json +++ b/composer.json @@ -59,8 +59,14 @@ "wp-cli/language-command": "^2", "wp-coding-standards/wpcs": "^2" }, + "autoload": { + "psr-4": { + "UserSwitching\\Tests\\": "tests/wpunit" + } + }, "scripts": { "post-update-cmd": [ + "@php -r \"! file_exists( __DIR__ . '/tests/wordpress/wp-content/plugins/user-switching' ) && symlink( __DIR__, __DIR__ . '/tests/wordpress/wp-content/plugins/user-switching' );\"", "@php -r \"! file_exists( 'tests/.env' ) && copy( 'tests/.env.dist', 'tests/.env' );\"" ], "test:cs": [ diff --git a/tests/_data/.gitkeep b/tests/_data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/_output/.gitkeep b/tests/_output/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/wpunit.suite.yml b/tests/wpunit.suite.yml index 312af0c..75cf170 100644 --- a/tests/wpunit.suite.yml +++ b/tests/wpunit.suite.yml @@ -9,6 +9,7 @@ modules: config: WPLoader: wpRootFolder: "tests/wordpress" + configFile: "vendor/autoload.php" dbName: "%WP_TESTS_DB_NAME%" dbHost: "%WP_TESTS_DB_HOST%" dbUser: "%WP_TESTS_DB_USER%" From 6c614e8be5fd18c5e8ef383cb0f8c6f05f40022b Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 20:01:02 +0100 Subject: [PATCH 043/270] Move the tests. --- tests/{test-auth.php => wpunit/authTest.php} | 6 +++++- tests/{test-caps.php => wpunit/capsTest.php} | 4 +++- tests/{test-plugin.php => wpunit/pluginTest.php} | 8 +++++--- tests/{test-sessions.php => wpunit/sessionsTest.php} | 6 +++++- tests/{test-switching.php => wpunit/switchingTest.php} | 6 +++++- tests/{user-switching-test.php => wpunit/test.php} | 6 ++++-- 6 files changed, 27 insertions(+), 9 deletions(-) rename tests/{test-auth.php => wpunit/authTest.php} (97%) rename tests/{test-caps.php => wpunit/capsTest.php} (99%) rename tests/{test-plugin.php => wpunit/pluginTest.php} (80%) rename tests/{test-sessions.php => wpunit/sessionsTest.php} (99%) rename tests/{test-switching.php => wpunit/switchingTest.php} (98%) rename tests/{user-switching-test.php => wpunit/test.php} (94%) diff --git a/tests/test-auth.php b/tests/wpunit/authTest.php similarity index 97% rename from tests/test-auth.php rename to tests/wpunit/authTest.php index d9bf67f..e9ba1ff 100644 --- a/tests/test-auth.php +++ b/tests/wpunit/authTest.php @@ -2,10 +2,14 @@ declare(strict_types = 1); +namespace UserSwitching\Tests; + +use user_switching; + /** * @covers \user_switching::authenticate_old_user */ -class TestAuthentication extends User_Switching_Test { +class Authentication extends Test { public function testValidCookiePassesAuthentication() : void { $expiry = time() + 172800; diff --git a/tests/test-caps.php b/tests/wpunit/capsTest.php similarity index 99% rename from tests/test-caps.php rename to tests/wpunit/capsTest.php index cb35754..5f1b83e 100644 --- a/tests/test-caps.php +++ b/tests/wpunit/capsTest.php @@ -2,11 +2,13 @@ declare(strict_types = 1); +namespace UserSwitching\Tests; + /** * @covers \user_switching::filter_user_has_cap * @covers \user_switching::filter_map_meta_cap */ -class TestCapabilities extends User_Switching_Test { +class Capabilities extends Test { /** * @return array> diff --git a/tests/test-plugin.php b/tests/wpunit/pluginTest.php similarity index 80% rename from tests/test-plugin.php rename to tests/wpunit/pluginTest.php index dd1edc7..ea22dea 100644 --- a/tests/test-plugin.php +++ b/tests/wpunit/pluginTest.php @@ -2,7 +2,9 @@ declare(strict_types = 1); -class TestReadme extends WP_UnitTestCase { +namespace UserSwitching\Tests; + +class Readme extends Test { /** * @var ?array */ @@ -14,7 +16,7 @@ public function testStableTagMatchesVersion() : void { self::fail( 'There is no readme file' ); } - $plugin_data = get_plugin_data( dirname( dirname( __FILE__ ) ) . '/user-switching.php' ); + $plugin_data = get_plugin_data( dirname( dirname( __DIR__ ) ) . '/user-switching.php' ); self::assertEquals( $readme_data['stable_tag'], $plugin_data['Version'] ); } @@ -24,7 +26,7 @@ public function testStableTagMatchesVersion() : void { */ private function get_readme() :? array { if ( ! isset( $this->readme_data ) ) { - $file = dirname( dirname( __FILE__ ) ) . '/readme.md'; + $file = dirname( dirname( __DIR__ ) ) . '/readme.md'; if ( ! is_file( $file ) ) { return null; diff --git a/tests/test-sessions.php b/tests/wpunit/sessionsTest.php similarity index 99% rename from tests/test-sessions.php rename to tests/wpunit/sessionsTest.php index e7b4f67..e18b7b6 100644 --- a/tests/test-sessions.php +++ b/tests/wpunit/sessionsTest.php @@ -2,7 +2,11 @@ declare(strict_types = 1); -class TestSessions extends User_Switching_Test { +namespace UserSwitching\Tests; + +use user_switching; + +class Sessions extends Test { /** * @covers \switch_to_user diff --git a/tests/test-switching.php b/tests/wpunit/switchingTest.php similarity index 98% rename from tests/test-switching.php rename to tests/wpunit/switchingTest.php index f3a8756..bef24f0 100644 --- a/tests/test-switching.php +++ b/tests/wpunit/switchingTest.php @@ -2,7 +2,11 @@ declare(strict_types = 1); -class TestSwitching extends User_Switching_Test { +namespace UserSwitching\Tests; + +use user_switching; + +class Switching extends Test { /** * @var int|false diff --git a/tests/user-switching-test.php b/tests/wpunit/test.php similarity index 94% rename from tests/user-switching-test.php rename to tests/wpunit/test.php index 49b3f9e..91c3bc1 100644 --- a/tests/user-switching-test.php +++ b/tests/wpunit/test.php @@ -2,7 +2,9 @@ declare(strict_types = 1); -abstract class User_Switching_Test extends WP_UnitTestCase { +namespace UserSwitching\Tests; + +abstract class Test extends \Codeception\TestCase\WPTestCase { /** * @var WP_User[] @@ -22,7 +24,7 @@ abstract class User_Switching_Test extends WP_UnitTestCase { /** * @return void */ - public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) { + public static function wpSetUpBeforeClass( \WP_UnitTest_Factory $factory ) { $roles = array( 'admin' => 'administrator', 'editor' => 'editor', From 30af6a35683f259063bf296c11c39a90fb819e0b Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 20:02:51 +0100 Subject: [PATCH 044/270] CI config. --- .github/workflows/test.yml | 3 +-- composer.json | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 02dda63..a80e50e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -74,8 +74,7 @@ jobs: sudo systemctl start mysql.service composer install --prefer-dist composer require --dev --update-with-dependencies --prefer-dist roots/wordpress="${{ matrix.wp }} || *" wp-phpunit/wp-phpunit="${{ matrix.wp }} || *" + mysqladmin -uroot -proot create wordpress_test - name: Run the tests run: composer test:ut - env: - WP_TESTS_DB_PASS: root diff --git a/composer.json b/composer.json index 4584d0e..02a2ac0 100644 --- a/composer.json +++ b/composer.json @@ -76,9 +76,7 @@ "phpstan analyze" ], "test:ut": [ - "wp db reset --yes --path=tests/wordpress #", - "export WP_MULTISITE=0 && phpunit --verbose --colors=always --exclude-group=ms-required", - "export WP_MULTISITE=1 && phpunit --verbose --colors=always --exclude-group=ms-excluded" + "codecept run wpunit" ], "test:ft": [ "bin/test.sh" From 1cc4b5b777ce177c2024ea9a5b863a88a54ad363 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 20:03:03 +0100 Subject: [PATCH 045/270] Docs. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 14868be..d8bbf1f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -54,7 +54,7 @@ You can clone this repo and activate it like a normal WordPress plugin. If you w ## Running the Tests -To run the whole test suite which includes PHPUnit unit tests, PHPCS code sniffs, PHPStan static analysis, and WordHat functional tests: +To run the whole test suite: composer test From 1dd21df3b0233403e6d0a5b51cc4ce957e060ba4 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 20:08:41 +0100 Subject: [PATCH 046/270] Add names to data provider elements. --- tests/wpunit/capsTest.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/wpunit/capsTest.php b/tests/wpunit/capsTest.php index 5f1b83e..7dc0bbc 100644 --- a/tests/wpunit/capsTest.php +++ b/tests/wpunit/capsTest.php @@ -11,38 +11,38 @@ class Capabilities extends Test { /** - * @return array> + * @return array> */ public function data_roles() : array { $roles = [ - [ + 'admin' => [ 'admin', ! is_multisite(), ], - [ + 'editor' => [ 'editor', false, ], - [ + 'author' => [ 'author', false, ], - [ + 'contributor' => [ 'contributor', false, ], - [ + 'subscriber' => [ 'subscriber', false, ], - [ + 'none' => [ 'no_role', false, ], ]; if ( is_multisite() ) { - $roles[] = [ + $roles['super admin'] = [ 'super', true, ]; From b3514ea6fc19a8da2dcd355a64f316c34266716c Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 20:10:19 +0100 Subject: [PATCH 047/270] Import the session tokens class. --- tests/wpunit/sessionsTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/wpunit/sessionsTest.php b/tests/wpunit/sessionsTest.php index e18b7b6..bcb11cd 100644 --- a/tests/wpunit/sessionsTest.php +++ b/tests/wpunit/sessionsTest.php @@ -5,6 +5,7 @@ namespace UserSwitching\Tests; use user_switching; +use WP_Session_Tokens; class Sessions extends Test { From 338df1a1962b77708098b418bb4d1547d70910f2 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 20:22:54 +0100 Subject: [PATCH 048/270] Switch to master for WPBrowser for now. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 02a2ac0..3a1f52c 100644 --- a/composer.json +++ b/composer.json @@ -44,7 +44,7 @@ "codeception/module-phpbrowser": "^1.0", "codeception/module-webdriver": "^1.0", "codeception/util-universalframework": "^1.0", - "lucatume/wp-browser": "^3.0", + "lucatume/wp-browser": "dev-master", "php-stubs/wordpress-stubs": "*", "phpcompatibility/php-compatibility": "^9", "phpstan/phpstan": "^1.0", From 6432c8737276db025348b5ffd0f426872023b051 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 20:39:54 +0100 Subject: [PATCH 049/270] Replace the manual symlink with Codeception configuration. --- codeception.dist.yml | 6 ++++++ composer.json | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/codeception.dist.yml b/codeception.dist.yml index 99ea77e..31e5659 100644 --- a/codeception.dist.yml +++ b/codeception.dist.yml @@ -8,5 +8,11 @@ actor_suffix: Tester extensions: enabled: - Codeception\Extension\RunFailed + - tad\WPBrowser\Extension\Symlinker + config: + tad\WPBrowser\Extension\Symlinker: + mode: plugin + destination: + default: tests/wordpress/wp-content/plugins params: - tests/.env diff --git a/composer.json b/composer.json index 3a1f52c..52a4f92 100644 --- a/composer.json +++ b/composer.json @@ -66,7 +66,6 @@ }, "scripts": { "post-update-cmd": [ - "@php -r \"! file_exists( __DIR__ . '/tests/wordpress/wp-content/plugins/user-switching' ) && symlink( __DIR__, __DIR__ . '/tests/wordpress/wp-content/plugins/user-switching' );\"", "@php -r \"! file_exists( 'tests/.env' ) && copy( 'tests/.env.dist', 'tests/.env' );\"" ], "test:cs": [ From f2a864c077d7239b68e0e0eaf9b24abe673b6ae8 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 20:46:28 +0100 Subject: [PATCH 050/270] Reimplement the single site and multisite testing. --- composer.json | 3 ++- tests/wpunit.suite.yml | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 52a4f92..47a8bf6 100644 --- a/composer.json +++ b/composer.json @@ -75,7 +75,8 @@ "phpstan analyze" ], "test:ut": [ - "codecept run wpunit" + "codecept run wpunit --env singlesite --skip-group ms-required", + "codecept run wpunit --env multisite --skip-group ms-excluded" ], "test:ft": [ "bin/test.sh" diff --git a/tests/wpunit.suite.yml b/tests/wpunit.suite.yml index 75cf170..e261be7 100644 --- a/tests/wpunit.suite.yml +++ b/tests/wpunit.suite.yml @@ -16,3 +16,14 @@ modules: dbPassword: "%WP_TESTS_DB_PASS%" plugins: ['user-switching/user-switching.php'] activatePlugins: ['user-switching/user-switching.php'] +env: + singlesite: + modules: + config: + WPLoader: + multisite: false + multisite: + modules: + config: + WPLoader: + multisite: true From 8da3caeb790e751d7a0730b47de9cdf46911a1ed Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 21:59:06 +0100 Subject: [PATCH 051/270] This doesn't exist yet but it may do. --- tests/wpunit.suite.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/wpunit.suite.yml b/tests/wpunit.suite.yml index e261be7..5d9474a 100644 --- a/tests/wpunit.suite.yml +++ b/tests/wpunit.suite.yml @@ -14,6 +14,7 @@ modules: dbHost: "%WP_TESTS_DB_HOST%" dbUser: "%WP_TESTS_DB_USER%" dbPassword: "%WP_TESTS_DB_PASS%" + skipPluggables: true plugins: ['user-switching/user-switching.php'] activatePlugins: ['user-switching/user-switching.php'] env: From 049855f39d880b0d1828d3d9d788a7b35c38f5e2 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 22:01:32 +0100 Subject: [PATCH 052/270] This no longer exists. --- phpstan.neon.dist | 1 - 1 file changed, 1 deletion(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 8d0d8f9..62484a1 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -18,7 +18,6 @@ parameters: scanDirectories: - tests - vendor/johnbillion/php-docs-standards - - vendor/wp-phpunit/wp-phpunit/includes scanFiles: - user-switching.php bootstrapFiles: From e50766e93fe7b790ec3e05fa15c6fb17647922b2 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 22:10:04 +0100 Subject: [PATCH 053/270] Invalidate the Composer cache on GHA. --- .github/workflows/coding-standards.yml | 2 +- .github/workflows/e2e.yml | 2 +- .github/workflows/test.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 0dc9c31..3cd9953 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -42,7 +42,7 @@ jobs: cache-name: cache-composer-dependencies with: path: ${{ steps.composer-cache.outputs.dir }} - key: 7.3-composer-${{ hashFiles('composer.json') }} + key: 7.3-composer-${{ hashFiles('composer.json') }}-v2 - name: PHPCS and PHPStan cache uses: actions/cache@v2 diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index dcc6106..05c9fea 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -53,7 +53,7 @@ jobs: cache-name: cache-composer-dependencies with: path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} + key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}-v2 - name: Install PHP uses: shivammathur/setup-php@2.7.0 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a80e50e..80de4f7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -51,7 +51,7 @@ jobs: cache-name: cache-composer-dependencies with: path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} + key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}-v2 - name: Install PHP uses: shivammathur/setup-php@2.7.0 From 02579328f51acb2de8621c71bdf01b0b773c6f66 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 22:17:15 +0100 Subject: [PATCH 054/270] Rename this (1/2). --- tests/wpunit/{test.php => xTest.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/wpunit/{test.php => xTest.php} (100%) diff --git a/tests/wpunit/test.php b/tests/wpunit/xTest.php similarity index 100% rename from tests/wpunit/test.php rename to tests/wpunit/xTest.php From 5768ef47fcbe855a30e81d1822c0487963287653 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 22:17:32 +0100 Subject: [PATCH 055/270] Rename this (2/2). --- tests/wpunit/{xTest.php => Test.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/wpunit/{xTest.php => Test.php} (100%) diff --git a/tests/wpunit/xTest.php b/tests/wpunit/Test.php similarity index 100% rename from tests/wpunit/xTest.php rename to tests/wpunit/Test.php From e7b0c19096d89d3f92cf90abdbc54626ac43cee8 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 22:19:56 +0100 Subject: [PATCH 056/270] Revert "Invalidate the Composer cache on GHA." This reverts commit e50766e93fe7b790ec3e05fa15c6fb17647922b2. --- .github/workflows/coding-standards.yml | 2 +- .github/workflows/e2e.yml | 2 +- .github/workflows/test.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 3cd9953..0dc9c31 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -42,7 +42,7 @@ jobs: cache-name: cache-composer-dependencies with: path: ${{ steps.composer-cache.outputs.dir }} - key: 7.3-composer-${{ hashFiles('composer.json') }}-v2 + key: 7.3-composer-${{ hashFiles('composer.json') }} - name: PHPCS and PHPStan cache uses: actions/cache@v2 diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 05c9fea..dcc6106 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -53,7 +53,7 @@ jobs: cache-name: cache-composer-dependencies with: path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}-v2 + key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} - name: Install PHP uses: shivammathur/setup-php@2.7.0 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 80de4f7..a80e50e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -51,7 +51,7 @@ jobs: cache-name: cache-composer-dependencies with: path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}-v2 + key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} - name: Install PHP uses: shivammathur/setup-php@2.7.0 From d70d7e59bfe9000e75eb2e1a2a126aab0f9352bd Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 22:39:03 +0100 Subject: [PATCH 057/270] Update some inline docs. --- tests/wpunit/Test.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/wpunit/Test.php b/tests/wpunit/Test.php index 91c3bc1..3ac61f4 100644 --- a/tests/wpunit/Test.php +++ b/tests/wpunit/Test.php @@ -7,12 +7,12 @@ abstract class Test extends \Codeception\TestCase\WPTestCase { /** - * @var WP_User[] + * @var \WP_User[] */ protected static $users = array(); /** - * @var WP_User[] + * @var \WP_User[] */ protected static $testers = array(); From d26a23d8ef96ac35651591aa1f790b043bb5bccc Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 22:43:07 +0100 Subject: [PATCH 058/270] Remove old files. --- .distignore | 2 +- phpunit.xml.dist | 24 ---------------------- tests/includes/bootstrap.php | 15 -------------- tests/wp-tests-config.php | 40 ------------------------------------ 4 files changed, 1 insertion(+), 80 deletions(-) delete mode 100644 phpunit.xml.dist delete mode 100644 tests/includes/bootstrap.php delete mode 100644 tests/wp-tests-config.php diff --git a/.distignore b/.distignore index 3da91f6..11a11f4 100644 --- a/.distignore +++ b/.distignore @@ -12,6 +12,7 @@ vendor .distignore .gitignore behat.yml +codeception.dist.yml composer.json composer.lock CONTRIBUTING.md @@ -20,5 +21,4 @@ package-lock.json package.json phpcs.xml.dist phpstan.neon.dist -phpunit.xml.dist SECURITY.md diff --git a/phpunit.xml.dist b/phpunit.xml.dist deleted file mode 100644 index d69be5c..0000000 --- a/phpunit.xml.dist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - ./tests/ - - - - - user-switching.php - - - diff --git a/tests/includes/bootstrap.php b/tests/includes/bootstrap.php deleted file mode 100644 index a8ce369..0000000 --- a/tests/includes/bootstrap.php +++ /dev/null @@ -1,15 +0,0 @@ -load(); -} - -// Path to the WordPress codebase to test. -define( 'ABSPATH', $root . '/' . $composer['extra']['wordpress-install-dir'] . '/' ); - -// Path to the theme to test with. -define( 'WP_DEFAULT_THEME', 'default' ); - -// Test with WordPress debug mode (default). -define( 'WP_DEBUG', true ); - -// WARNING WARNING WARNING! -// These tests will DROP ALL TABLES in the database with the prefix named below. -// DO NOT use a production database or one that is shared with something else. -define( 'DB_NAME', getenv( 'WP_TESTS_DB_NAME' ) ?: 'wordpress_test' ); -define( 'DB_USER', getenv( 'WP_TESTS_DB_USER' ) ?: 'root' ); -define( 'DB_PASSWORD', getenv( 'WP_TESTS_DB_PASS' ) ?: '' ); -define( 'DB_HOST', getenv( 'WP_TESTS_DB_HOST' ) ?: 'localhost' ); -define( 'DB_CHARSET', 'utf8' ); -define( 'DB_COLLATE', '' ); - -// Test suite configuration. -define( 'WP_TESTS_DOMAIN', 'example.org' ); -define( 'WP_TESTS_EMAIL', 'admin@example.org' ); -define( 'WP_TESTS_TITLE', 'User Switching Tests' ); -define( 'WP_PHP_BINARY', 'php' ); From bc2aca689401a06d401328f4979db98a52b68be7 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 22:45:00 +0100 Subject: [PATCH 059/270] Update PHPStan config. --- phpstan.neon.dist | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 62484a1..eed764f 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -7,19 +7,10 @@ parameters: tmpDir: tests/cache paths: - user-switching.php - - tests + - tests/wpunit excludePaths: - analyse: - - tests/cache - - tests/stubs.php + analyseAndScan: - tests/wordpress - - tests/wp-config.php - - tests/wp-tests-config.php - scanDirectories: - - tests - - vendor/johnbillion/php-docs-standards - scanFiles: - - user-switching.php bootstrapFiles: - tests/stubs.php ignoreErrors: From 70c4964600682cc1bd9c14bdec3001420681ac24 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 23:25:25 +0100 Subject: [PATCH 060/270] This test has run its course. --- composer.json | 1 - tests/test-docs.php | 31 ------------------------------- 2 files changed, 32 deletions(-) delete mode 100644 tests/test-docs.php diff --git a/composer.json b/composer.json index 47a8bf6..a571a8f 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,6 @@ "behat/mink-goutte-driver": "^1.2", "dealerdirect/phpcodesniffer-composer-installer": "0.7.0", "genesis/behat-fail-aid": "^2.0", - "johnbillion/php-docs-standards": "*", "johnbillion/wordhat": "dev-develop", "codeception/module-asserts": "^1.0", "codeception/module-cli": "^1.0", diff --git a/tests/test-docs.php b/tests/test-docs.php deleted file mode 100644 index e7cbdae..0000000 --- a/tests/test-docs.php +++ /dev/null @@ -1,31 +0,0 @@ - - */ - protected function getTestFunctions() : array { - return array( - 'user_switching_set_olduser_cookie', - 'user_switching_clear_olduser_cookie', - 'user_switching_get_olduser_cookie', - 'user_switching_get_auth_cookie', - 'switch_to_user', - 'switch_off_user', - 'current_user_switched', - ); - } - - /** - * @return array - */ - protected function getTestClasses() : array { - return array( - 'user_switching', - ); - } - -} From 21a92f27154a59ff99375d6ff7cacea880d36fef Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 23:29:26 +0100 Subject: [PATCH 061/270] Update PHPUnit. --- composer.json | 2 +- tests/wpunit/Test.php | 2 +- tests/wpunit/switchingTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index a571a8f..57fb444 100644 --- a/composer.json +++ b/composer.json @@ -49,7 +49,7 @@ "phpstan/phpstan": "^1.0", "phpstan/phpstan-deprecation-rules": "^1.0", "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^7", + "phpunit/phpunit": "^9", "roots/wordpress": "*", "szepeviktor/phpstan-wordpress": "^1.0", "vlucas/phpdotenv": "^3", diff --git a/tests/wpunit/Test.php b/tests/wpunit/Test.php index 3ac61f4..d18a2d2 100644 --- a/tests/wpunit/Test.php +++ b/tests/wpunit/Test.php @@ -60,7 +60,7 @@ public static function wpSetUpBeforeClass( \WP_UnitTest_Factory $factory ) { /** * @return void */ - public function setUp() { + public function setUp(): void { parent::setUp(); add_action( 'set_auth_cookie', array( $this, 'action_set_auth_cookie' ), 10, 6 ); diff --git a/tests/wpunit/switchingTest.php b/tests/wpunit/switchingTest.php index bef24f0..d995324 100644 --- a/tests/wpunit/switchingTest.php +++ b/tests/wpunit/switchingTest.php @@ -28,7 +28,7 @@ class Switching extends Test { */ public $test_switching_auth_cookie_remember; - public function setUp() { + public function setUp(): void { parent::setUp(); add_action( 'switch_to_user', array( $this, '_action_switch_user' ), 10, 2 ); From c1a7488fc730375a100fdc6fb79b8ec15054d5cc Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 23:30:54 +0100 Subject: [PATCH 062/270] Test on PHP 8 too. --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a80e50e..ff67615 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: build: strategy: matrix: - php: ['7.3'] + php: ['8.0','7.3'] wp: ['*', 'dev-nightly'] fail-fast: false name: WP ${{ matrix.wp }} / PHP ${{ matrix.php }} From b659f0aae291755bfde00851c748e9528595bdf1 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 23:32:00 +0100 Subject: [PATCH 063/270] The functional tests run on PHP 8 now, too. --- .github/workflows/e2e.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index dcc6106..f049111 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -33,7 +33,7 @@ jobs: build: strategy: matrix: - php: ['7.4'] + php: ['8.0','7.4'] wp: ['*', 'dev-nightly'] fail-fast: false name: WP ${{ matrix.wp }} / PHP ${{ matrix.php }} From 1911a8dd24cf151fb80ecdf151f396ce63f55960 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 23:46:25 +0100 Subject: [PATCH 064/270] Switch to patching wp-browser for now. --- composer.json | 9 ++++++++- tests/patches/wp-browser.patch | 25 +++++++++++++++++++++++++ tests/wpunit.suite.yml | 1 - 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 tests/patches/wp-browser.patch diff --git a/composer.json b/composer.json index 57fb444..6a899af 100644 --- a/composer.json +++ b/composer.json @@ -20,11 +20,17 @@ "allow-plugins": { "composer/installers": true, "composer/package-versions-deprecated": true, + "cweagans/composer-patches": true, "dealerdirect/phpcodesniffer-composer-installer": true, "roots/wordpress-core-installer": true } }, "extra": { + "patches": { + "lucatume/wp-browser": { + "Remove pluggable function definitions": "tests/patches/wp-browser.patch" + } + }, "wordpress-install-dir": "tests/wordpress" }, "require": { @@ -43,7 +49,8 @@ "codeception/module-phpbrowser": "^1.0", "codeception/module-webdriver": "^1.0", "codeception/util-universalframework": "^1.0", - "lucatume/wp-browser": "dev-master", + "cweagans/composer-patches": "^1.7", + "lucatume/wp-browser": "3.0.17", "php-stubs/wordpress-stubs": "*", "phpcompatibility/php-compatibility": "^9", "phpstan/phpstan": "^1.0", diff --git a/tests/patches/wp-browser.patch b/tests/patches/wp-browser.patch new file mode 100644 index 0000000..5e004ef --- /dev/null +++ b/tests/patches/wp-browser.patch @@ -0,0 +1,25 @@ +diff --git a/src/includes/functions.php b/src/includes/functions.php +index 235a9519..178d630a 100644 +--- a/src/includes/functions.php ++++ b/src/includes/functions.php +@@ -196,20 +196,3 @@ function _upload_dir_https($uploads) + + return $uploads; + } +- +-if (! function_exists('wp_set_auth_cookie') && ! function_exists('wp_clear_auth_cookie')) { +- // No `setcookie` calls to avoid: "Cannot modify header information - headers already sent" +- function wp_set_auth_cookie($user_id, $remember = false, $secure = '', $token = '') +- { +- /** This action is documented in wp-inclues/pluggable.php */ +- do_action('set_auth_cookie', null, null, null, $user_id, null); +- /** This action is documented in wp-inclues/pluggable.php */ +- do_action('set_logged_in_cookie', null, null, null, $user_id, 'logged_in'); +- } +- +- function wp_clear_auth_cookie() +- { +- /** This action is documented in wp-inclues/pluggable.php */ +- do_action('clear_auth_cookie'); +- } +-} diff --git a/tests/wpunit.suite.yml b/tests/wpunit.suite.yml index 5d9474a..e261be7 100644 --- a/tests/wpunit.suite.yml +++ b/tests/wpunit.suite.yml @@ -14,7 +14,6 @@ modules: dbHost: "%WP_TESTS_DB_HOST%" dbUser: "%WP_TESTS_DB_USER%" dbPassword: "%WP_TESTS_DB_PASS%" - skipPluggables: true plugins: ['user-switching/user-switching.php'] activatePlugins: ['user-switching/user-switching.php'] env: From 067ffbb857ee0e333ee6b569fb8bae10b112308f Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 4 Jan 2022 23:49:06 +0100 Subject: [PATCH 065/270] Don't need any of these currently. --- composer.json | 7 ------- 1 file changed, 7 deletions(-) diff --git a/composer.json b/composer.json index 6a899af..c20dba0 100644 --- a/composer.json +++ b/composer.json @@ -42,13 +42,6 @@ "dealerdirect/phpcodesniffer-composer-installer": "0.7.0", "genesis/behat-fail-aid": "^2.0", "johnbillion/wordhat": "dev-develop", - "codeception/module-asserts": "^1.0", - "codeception/module-cli": "^1.0", - "codeception/module-db": "^1.0", - "codeception/module-filesystem": "^1.0", - "codeception/module-phpbrowser": "^1.0", - "codeception/module-webdriver": "^1.0", - "codeception/util-universalframework": "^1.0", "cweagans/composer-patches": "^1.7", "lucatume/wp-browser": "3.0.17", "php-stubs/wordpress-stubs": "*", From 90e07967d37ae01b0d14e7acf2fcd4ca31d427c1 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 00:10:45 +0100 Subject: [PATCH 066/270] Skip scanning the test files with PHPStan because something in the wp-browser autoloader is breaking it. --- phpstan.neon.dist | 4 ---- 1 file changed, 4 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index eed764f..76a5ee5 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -7,10 +7,6 @@ parameters: tmpDir: tests/cache paths: - user-switching.php - - tests/wpunit - excludePaths: - analyseAndScan: - - tests/wordpress bootstrapFiles: - tests/stubs.php ignoreErrors: From ca4e94df9ae6f0b804324e33a1e63a348d3ade38 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 00:13:29 +0100 Subject: [PATCH 067/270] Loosen all these dependencies. --- composer.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index c20dba0..818e09f 100644 --- a/composer.json +++ b/composer.json @@ -35,16 +35,15 @@ }, "require": { "php": ">=5.3", - "composer/installers": "^1" + "composer/installers": "*" }, "require-dev": { "behat/mink-goutte-driver": "^1.2", - "dealerdirect/phpcodesniffer-composer-installer": "0.7.0", + "dealerdirect/phpcodesniffer-composer-installer": "*", "genesis/behat-fail-aid": "^2.0", "johnbillion/wordhat": "dev-develop", "cweagans/composer-patches": "^1.7", "lucatume/wp-browser": "3.0.17", - "php-stubs/wordpress-stubs": "*", "phpcompatibility/php-compatibility": "^9", "phpstan/phpstan": "^1.0", "phpstan/phpstan-deprecation-rules": "^1.0", From 61774de457fba54eaf3803c95563909118e0ac8b Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 00:24:45 +0100 Subject: [PATCH 068/270] Be more specific about supported composer/installers versions. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 818e09f..b71f89d 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,7 @@ }, "require": { "php": ">=5.3", - "composer/installers": "*" + "composer/installers": "^1 || ^2" }, "require-dev": { "behat/mink-goutte-driver": "^1.2", From c5726e40682cfe1d969add20596e0a2745fd1c6e Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 00:46:12 +0100 Subject: [PATCH 069/270] Begin switching to WPBrowser for functional tests. --- .distignore | 1 - .github/workflows/e2e.yml | 4 ++-- behat.yml | 34 ----------------------------- bin/test.sh | 9 +++++--- composer.json | 4 +--- tests/_support/AcceptanceTester.php | 22 +++++++++++++++++++ tests/_support/FunctionalTester.php | 22 +++++++++++++++++++ tests/acceptance.suite.yml | 15 +++++++++++++ tests/functional.suite.yml | 15 +++++++++++++ tests/wp-config.php | 2 +- 10 files changed, 84 insertions(+), 44 deletions(-) delete mode 100644 behat.yml create mode 100644 tests/_support/AcceptanceTester.php create mode 100644 tests/_support/FunctionalTester.php create mode 100644 tests/acceptance.suite.yml create mode 100644 tests/functional.suite.yml diff --git a/.distignore b/.distignore index 11a11f4..8e8ce8f 100644 --- a/.distignore +++ b/.distignore @@ -11,7 +11,6 @@ vendor # Files .distignore .gitignore -behat.yml codeception.dist.yml composer.json composer.lock diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index f049111..9440ba0 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -9,7 +9,7 @@ on: - 'master' paths: - '.github/workflows/e2e.yml' - - 'behat.yml' + - 'codeception.dist.yml' - 'bin/test.sh' - 'composer.json' - 'features/**' @@ -19,7 +19,7 @@ on: - '**' paths: - '.github/workflows/e2e.yml' - - 'behat.yml' + - 'codeception.dist.yml' - 'bin/test.sh' - 'composer.json' - 'features/**' diff --git a/behat.yml b/behat.yml deleted file mode 100644 index cc9e1c8..0000000 --- a/behat.yml +++ /dev/null @@ -1,34 +0,0 @@ -default: - suites: - default: - contexts: - - UserSwitchingContext - - WordHat\Extension\Context\WordpressContext - - Behat\MinkExtension\Context\MinkContext - - WordHat\Extension\Context\DashboardContext - - WordHat\Extension\Context\SiteContext - - WordHat\Extension\Context\UserContext - - FailAid\Context\FailureContext - - extensions: - Behat\MinkExtension: - base_url: 'http://localhost:8000' - default_session: default - sessions: - default: - goutte: - guzzle_parameters: - verify: false # Allow self-signed SSL certificates - - WordHat\Extension: - default_driver: wpphp - users: - - - roles: - - administrator - username: admin - password: admin - database: - restore_after_test: true - - FailAid\Extension: ~ diff --git a/bin/test.sh b/bin/test.sh index b75672d..2c0914a 100755 --- a/bin/test.sh +++ b/bin/test.sh @@ -26,10 +26,13 @@ $WP core install --title="Example" --admin_user="admin" --admin_password="admin" $WP language core install it_IT $WP language plugin install user-switching it_IT +# Run the acceptance tests: +TEST_SITE_WP_URL=$WP_URL \ + ./vendor/bin/codecept run acceptance --steps "$1" + # Run the functional tests: -BEHAT_PARAMS='{"extensions" : {"WordHat\\Extension" : {"path" : "'$WP_CORE_DIR'"}}}' \ - ./vendor/bin/behat --colors --strict "$1" \ - || BEHAT_EXIT_CODE=$? && kill $! && exit $BEHAT_EXIT_CODE +TEST_SITE_WP_URL=$WP_URL \ + ./vendor/bin/codecept run functional --steps "$1" # Stop the PHP web server: kill $! diff --git a/composer.json b/composer.json index b71f89d..dbe20b1 100644 --- a/composer.json +++ b/composer.json @@ -38,10 +38,8 @@ "composer/installers": "^1 || ^2" }, "require-dev": { - "behat/mink-goutte-driver": "^1.2", + "codeception/module-phpbrowser": "^1.0", "dealerdirect/phpcodesniffer-composer-installer": "*", - "genesis/behat-fail-aid": "^2.0", - "johnbillion/wordhat": "dev-develop", "cweagans/composer-patches": "^1.7", "lucatume/wp-browser": "3.0.17", "phpcompatibility/php-compatibility": "^9", diff --git a/tests/_support/AcceptanceTester.php b/tests/_support/AcceptanceTester.php new file mode 100644 index 0000000..06793fe --- /dev/null +++ b/tests/_support/AcceptanceTester.php @@ -0,0 +1,22 @@ + Date: Wed, 5 Jan 2022 00:52:29 +0100 Subject: [PATCH 070/270] Put some placeholder step definitions in place. --- tests/_support/AcceptanceTester.php | 5 +-- tests/_support/FunctionalTester.php | 58 ++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/tests/_support/AcceptanceTester.php b/tests/_support/AcceptanceTester.php index 06793fe..eb5cc43 100644 --- a/tests/_support/AcceptanceTester.php +++ b/tests/_support/AcceptanceTester.php @@ -13,10 +13,7 @@ * @method void comment($description) * @method void pause() */ -class AcceptanceTester extends \Codeception\Actor { +class AcceptanceTester extends FunctionalTester { use _generated\AcceptanceTesterActions; - /** - * Define custom actions here - */ } diff --git a/tests/_support/FunctionalTester.php b/tests/_support/FunctionalTester.php index 7e4f50f..f927136 100644 --- a/tests/_support/FunctionalTester.php +++ b/tests/_support/FunctionalTester.php @@ -17,6 +17,62 @@ class FunctionalTester extends \Codeception\Actor { use _generated\FunctionalTesterActions; /** - * Define custom actions here + * Switch to the specified user + * + * @param string $user_id */ + public function switchToUser( $user_id ) { + throw new \Exception( 'Not implemented' ); + } + + /** + * Switch off + */ + public function switchOff() { + throw new \Exception( 'Not implemented' ); + } + + /** + * Switch back to the original user + * + * @param string $user_id + */ + public function switchBack( $user_id ) { + throw new \Exception( 'Not implemented' ); + } + + /** + * Verify that the user is logged in as the specified user + * + * @param string $user_id + */ + public function loggedInAs( $user_id ) { + throw new \Exception( 'Not implemented' ); + } + + /** + * Verify that the user is logged out + */ + public function loggedOut() { + throw new \Exception( 'Not implemented' ); + } + + /** + * Verify the page language + * + * @param string $lang + */ + public function thePageLanguageShouldBe( $lang ) { + throw new \Exception( 'Not implemented' ); + } + + /** + * Verify the language of an element + * + * @param string $selector + * @param string $lang + */ + public function theElementLanguageShouldBe( $selector, $lang ) { + throw new \Exception( 'Not implemented' ); + } } From 1b27491c25d7280a5b703d565dfb30f8dea732d9 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 01:35:41 +0100 Subject: [PATCH 071/270] Add the admin notice steps from WP Crontrol. --- tests/_support/FunctionalTester.php | 36 +++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/_support/FunctionalTester.php b/tests/_support/FunctionalTester.php index f927136..21b1fba 100644 --- a/tests/_support/FunctionalTester.php +++ b/tests/_support/FunctionalTester.php @@ -75,4 +75,40 @@ public function thePageLanguageShouldBe( $lang ) { public function theElementLanguageShouldBe( $selector, $lang ) { throw new \Exception( 'Not implemented' ); } + + /** + * Checks that the current page contains an admin success notice. + * + * @param string $text The message text to search for. + */ + public function seeAdminSuccessNotice( string $text ) { + return $this->see( $text, '.notice-success' ); + } + + /** + * Checks that the current page contains an admin success notice. + * + * @param string $text The message text to search for. + */ + public function seeAdminWarningNotice( string $text ) { + return $this->see( $text, '.notice-warning' ); + } + + /** + * Checks that the current page contains an admin success notice. + * + * @param string $text The message text to search for. + */ + public function seeAdminErrorNotice( string $text ) { + return $this->see( $text, '.notice-error' ); + } + + /** + * Checks that the current page contains an admin success notice. + * + * @param string $text The message text to search for. + */ + public function seeAdminInfoNotice( string $text ) { + return $this->see( $text, '.notice-info' ); + } } From 84824923eedd08c80a671049b7bede9de52d14e9 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 01:47:56 +0100 Subject: [PATCH 072/270] Activate the plugin via WP-CLI for now. --- bin/test.sh | 3 +++ composer.json | 1 + 2 files changed, 4 insertions(+) diff --git a/bin/test.sh b/bin/test.sh index 2c0914a..79d51ee 100755 --- a/bin/test.sh +++ b/bin/test.sh @@ -22,6 +22,9 @@ $WP db reset --yes # Install WordPress: $WP core install --title="Example" --admin_user="admin" --admin_password="admin" --admin_email="admin@example.com" +# Activate the plugin: +$WP plugin activate user-switching + # Install language files: $WP language core install it_IT $WP language plugin install user-switching it_IT diff --git a/composer.json b/composer.json index dbe20b1..276704e 100644 --- a/composer.json +++ b/composer.json @@ -52,6 +52,7 @@ "vlucas/phpdotenv": "^3", "wp-cli/core-command": "^2", "wp-cli/db-command": "^2", + "wp-cli/extension-command": "^2", "wp-cli/language-command": "^2", "wp-coding-standards/wpcs": "^2" }, From a9596d473c79df2b4a24d3c1f0b4dc193c9b900f Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 01:48:34 +0100 Subject: [PATCH 073/270] Add the WPDb module. --- composer.json | 1 + tests/acceptance.suite.yml | 9 +++++++++ tests/functional.suite.yml | 9 +++++++++ 3 files changed, 19 insertions(+) diff --git a/composer.json b/composer.json index 276704e..ff1bd51 100644 --- a/composer.json +++ b/composer.json @@ -38,6 +38,7 @@ "composer/installers": "^1 || ^2" }, "require-dev": { + "codeception/module-db": "^1.0", "codeception/module-phpbrowser": "^1.0", "dealerdirect/phpcodesniffer-composer-installer": "*", "cweagans/composer-patches": "^1.7", diff --git a/tests/acceptance.suite.yml b/tests/acceptance.suite.yml index 3d460f2..a349e4d 100644 --- a/tests/acceptance.suite.yml +++ b/tests/acceptance.suite.yml @@ -6,8 +6,17 @@ actor: AcceptanceTester modules: enabled: + - WPDb - WPBrowser config: + WPDb: + dsn: 'mysql:host=%WP_TESTS_DB_HOST%;dbname=%WP_TESTS_DB_NAME%' + user: '%WP_TESTS_DB_USER%' + password: '%WP_TESTS_DB_PASS%' + url: '%TEST_SITE_WP_URL%' + dump: false + populate: false + cleanup: false WPBrowser: url: '%TEST_SITE_WP_URL%' adminUsername: 'admin' diff --git a/tests/functional.suite.yml b/tests/functional.suite.yml index 3351fd6..4bd5f4e 100644 --- a/tests/functional.suite.yml +++ b/tests/functional.suite.yml @@ -6,8 +6,17 @@ actor: FunctionalTester modules: enabled: + - WPDb - WPBrowser config: + WPDb: + dsn: 'mysql:host=%WP_TESTS_DB_HOST%;dbname=%WP_TESTS_DB_NAME%' + user: '%WP_TESTS_DB_USER%' + password: '%WP_TESTS_DB_PASS%' + url: '%TEST_SITE_WP_URL%' + dump: false + populate: false + cleanup: false WPBrowser: url: '%TEST_SITE_WP_URL%' adminUsername: 'admin' From 74b12751de8e7e1cc26d3b33078a39cb593460c2 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 01:52:09 +0100 Subject: [PATCH 074/270] Use the newest CSS class names for the success message. --- user-switching.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/user-switching.php b/user-switching.php index 153f244..c262085 100644 --- a/user-switching.php +++ b/user-switching.php @@ -314,7 +314,7 @@ public function action_admin_notices() { } ?> -
+
-
+

Date: Wed, 5 Jan 2022 01:52:38 +0100 Subject: [PATCH 075/270] Begin implementing a scenario. --- tests/_support/FunctionalTester.php | 5 +++- tests/acceptance/SwitchUserCest.php | 37 +++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 tests/acceptance/SwitchUserCest.php diff --git a/tests/_support/FunctionalTester.php b/tests/_support/FunctionalTester.php index 21b1fba..e5e8da4 100644 --- a/tests/_support/FunctionalTester.php +++ b/tests/_support/FunctionalTester.php @@ -22,7 +22,10 @@ class FunctionalTester extends \Codeception\Actor { * @param string $user_id */ public function switchToUser( $user_id ) { - throw new \Exception( 'Not implemented' ); + $user_id = $this->grabUserIdFromDatabase( $user_id ); + + $this->amOnAdminPage( sprintf( 'user-edit.php?user_id=%d', $user_id ) ); + $this->click( '#user_switching_switcher' ); } /** diff --git a/tests/acceptance/SwitchUserCest.php b/tests/acceptance/SwitchUserCest.php new file mode 100644 index 0000000..3a9b105 --- /dev/null +++ b/tests/acceptance/SwitchUserCest.php @@ -0,0 +1,37 @@ +comment( 'As an administrator' ); + $I->comment( 'I need to be able to switch between users' ); + $I->comment( 'In order to access different user accounts' ); + + $I->haveUserInDatabase( 'editor', 'editor' ); + } + + public function SwitchToEditorAndBack( AcceptanceTester $I ) { + // Given I am logged in as admin + $I->loginAsAdmin(); + // When I switch to user "editor" + $I->switchToUser( 'editor' ); + // Then I should see a status message that says "Switched to editor" + $I->seeAdminSuccessNotice( 'Switched to editor' ); + // And I should be logged in as "editor" + $I->loggedInAs( 'editor' ); + + // When I go to the dashboard + $I->amOnAdminPage( '/' ); + // And I switch back to "admin" + $I->switchBack( 'admin' ); + // Then I should see a status message that says "Switched back to admin" + $I->seeAdminSuccessNotice( 'Switched back to admin' ); + // And I should be logged in as "admin" + $I->loggedInAs( 'admin' ); + } +} From b657ebeacaa1cad38d4005db110ccf2fe384c519 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 14:23:07 +0100 Subject: [PATCH 076/270] These are all user logins, not user IDs. --- tests/_support/FunctionalTester.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/_support/FunctionalTester.php b/tests/_support/FunctionalTester.php index e5e8da4..bc62011 100644 --- a/tests/_support/FunctionalTester.php +++ b/tests/_support/FunctionalTester.php @@ -19,10 +19,10 @@ class FunctionalTester extends \Codeception\Actor { /** * Switch to the specified user * - * @param string $user_id + * @param string $user_login */ - public function switchToUser( $user_id ) { - $user_id = $this->grabUserIdFromDatabase( $user_id ); + public function switchToUser( $user_login ) { + $user_id = $this->grabUserIdFromDatabase( $user_login ); $this->amOnAdminPage( sprintf( 'user-edit.php?user_id=%d', $user_id ) ); $this->click( '#user_switching_switcher' ); @@ -38,18 +38,18 @@ public function switchOff() { /** * Switch back to the original user * - * @param string $user_id + * @param string $user_login */ - public function switchBack( $user_id ) { + public function switchBack( $user_login ) { throw new \Exception( 'Not implemented' ); } /** * Verify that the user is logged in as the specified user * - * @param string $user_id + * @param string $user_login */ - public function loggedInAs( $user_id ) { + public function loggedInAs( $user_login ) { throw new \Exception( 'Not implemented' ); } From 78ebeb81f70c42189015e4d4781e65cdf8796dab Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 14:36:31 +0100 Subject: [PATCH 077/270] Make the process killer more explicit. --- bin/test.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/bin/test.sh b/bin/test.sh index 79d51ee..c18d5d6 100755 --- a/bin/test.sh +++ b/bin/test.sh @@ -15,6 +15,7 @@ WP="./vendor/bin/wp --color --path=$WP_CORE_DIR --url=http://$WP_URL" # Start the PHP server: php -S "$WP_URL" -t "$WP_CORE_DIR" -d disable_functions=mail 2>/dev/null & +PHP_SERVER_PROCESS_ID=$! # Reset or install the test database: $WP db reset --yes @@ -31,11 +32,13 @@ $WP language plugin install user-switching it_IT # Run the acceptance tests: TEST_SITE_WP_URL=$WP_URL \ - ./vendor/bin/codecept run acceptance --steps "$1" + ./vendor/bin/codecept run acceptance --steps "$1" \ + || TESTS_EXIT_CODE=$? && kill $PHP_SERVER_PROCESS_ID && exit $TESTS_EXIT_CODE # Run the functional tests: TEST_SITE_WP_URL=$WP_URL \ - ./vendor/bin/codecept run functional --steps "$1" + ./vendor/bin/codecept run functional --steps "$1" \ + || TESTS_EXIT_CODE=$? && kill $PHP_SERVER_PROCESS_ID && exit $TESTS_EXIT_CODE # Stop the PHP web server: -kill $! +kill $PHP_SERVER_PROCESS_ID From 7d08b9b3b4540ce39c27b6e1013f60bf6be0d5ac Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 14:36:42 +0100 Subject: [PATCH 078/270] Don't attempt to send this email during the test suite installation. --- bin/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/test.sh b/bin/test.sh index c18d5d6..3343892 100755 --- a/bin/test.sh +++ b/bin/test.sh @@ -21,7 +21,7 @@ PHP_SERVER_PROCESS_ID=$! $WP db reset --yes # Install WordPress: -$WP core install --title="Example" --admin_user="admin" --admin_password="admin" --admin_email="admin@example.com" +$WP core install --title="Example" --admin_user="admin" --admin_password="admin" --admin_email="admin@example.com" --skip-email # Activate the plugin: $WP plugin activate user-switching From 9338531c993d28d5a6a8038f429705d0c29f2a43 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 14:36:55 +0100 Subject: [PATCH 079/270] Implement more steps. --- tests/_support/FunctionalTester.php | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/tests/_support/FunctionalTester.php b/tests/_support/FunctionalTester.php index bc62011..8f23ae6 100644 --- a/tests/_support/FunctionalTester.php +++ b/tests/_support/FunctionalTester.php @@ -41,7 +41,19 @@ public function switchOff() { * @param string $user_login */ public function switchBack( $user_login ) { - throw new \Exception( 'Not implemented' ); + $display_name = $this->grabFromDatabase( + $this->grabUsersTableName(), + 'display_name', + [ + 'user_login' => $user_login, + ] + ); + + $this->click( sprintf( + 'Switch back to %1$s (%2$s)', + $display_name, + $user_login + ) ); } /** @@ -50,7 +62,18 @@ public function switchBack( $user_login ) { * @param string $user_login */ public function loggedInAs( $user_login ) { - throw new \Exception( 'Not implemented' ); + $display_name = $this->grabFromDatabase( + $this->grabUsersTableName(), + 'display_name', + [ + 'user_login' => $user_login, + ] + ); + + $this->see( + $display_name, + '#wpadminbar .display-name' + ); } /** From bb54c078b9d437389ac94844f754fee0775f4bb3 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 14:45:53 +0100 Subject: [PATCH 080/270] Implement more tests and steps. --- tests/_support/FunctionalTester.php | 5 +++-- tests/acceptance/SwitchUserCest.php | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/tests/_support/FunctionalTester.php b/tests/_support/FunctionalTester.php index 8f23ae6..fbae7df 100644 --- a/tests/_support/FunctionalTester.php +++ b/tests/_support/FunctionalTester.php @@ -32,7 +32,8 @@ public function switchToUser( $user_login ) { * Switch off */ public function switchOff() { - throw new \Exception( 'Not implemented' ); + $this->amOnAdminPage( '/' ); + $this->click( 'Switch Off' ); } /** @@ -80,7 +81,7 @@ public function loggedInAs( $user_login ) { * Verify that the user is logged out */ public function loggedOut() { - throw new \Exception( 'Not implemented' ); + $this->cantSeeElement( '#wpadminbar .display-name' ); } /** diff --git a/tests/acceptance/SwitchUserCest.php b/tests/acceptance/SwitchUserCest.php index 3a9b105..3cea12f 100644 --- a/tests/acceptance/SwitchUserCest.php +++ b/tests/acceptance/SwitchUserCest.php @@ -34,4 +34,18 @@ public function SwitchToEditorAndBack( AcceptanceTester $I ) { // And I should be logged in as "admin" $I->loggedInAs( 'admin' ); } + + public function SwitchOffAndBack( AcceptanceTester $I ) { + // Given I am logged in as admin + $I->loginAsAdmin(); + // When I switch off + $I->switchOff(); + // Then I should be logged out + $I->loggedOut(); + + // When I switch back to "admin" + $I->switchBack( 'admin' ); + // Then I should be logged in as "admin" + $I->loggedInAs( 'admin' ); + } } From f138de7757e2305294983afdff29c5aa324472f1 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 15:10:14 +0100 Subject: [PATCH 081/270] Run the functional tests first. --- bin/test.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/test.sh b/bin/test.sh index 3343892..277f4a2 100755 --- a/bin/test.sh +++ b/bin/test.sh @@ -30,14 +30,14 @@ $WP plugin activate user-switching $WP language core install it_IT $WP language plugin install user-switching it_IT -# Run the acceptance tests: +# Run the functional tests: TEST_SITE_WP_URL=$WP_URL \ - ./vendor/bin/codecept run acceptance --steps "$1" \ + ./vendor/bin/codecept run functional --steps "$1" \ || TESTS_EXIT_CODE=$? && kill $PHP_SERVER_PROCESS_ID && exit $TESTS_EXIT_CODE -# Run the functional tests: +# Run the acceptance tests: TEST_SITE_WP_URL=$WP_URL \ - ./vendor/bin/codecept run functional --steps "$1" \ + ./vendor/bin/codecept run acceptance --steps "$1" \ || TESTS_EXIT_CODE=$? && kill $PHP_SERVER_PROCESS_ID && exit $TESTS_EXIT_CODE # Stop the PHP web server: From 3da5a8e9bc76e4b7a7623278cae36698280e73fc Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 15:14:42 +0100 Subject: [PATCH 082/270] More logic fixing. --- bin/test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/test.sh b/bin/test.sh index 277f4a2..4d174e4 100755 --- a/bin/test.sh +++ b/bin/test.sh @@ -33,12 +33,12 @@ $WP language plugin install user-switching it_IT # Run the functional tests: TEST_SITE_WP_URL=$WP_URL \ ./vendor/bin/codecept run functional --steps "$1" \ - || TESTS_EXIT_CODE=$? && kill $PHP_SERVER_PROCESS_ID && exit $TESTS_EXIT_CODE + || ( TESTS_EXIT_CODE=$? && kill $PHP_SERVER_PROCESS_ID && exit $TESTS_EXIT_CODE ) # Run the acceptance tests: TEST_SITE_WP_URL=$WP_URL \ ./vendor/bin/codecept run acceptance --steps "$1" \ - || TESTS_EXIT_CODE=$? && kill $PHP_SERVER_PROCESS_ID && exit $TESTS_EXIT_CODE + || ( TESTS_EXIT_CODE=$? && kill $PHP_SERVER_PROCESS_ID && exit $TESTS_EXIT_CODE ) # Stop the PHP web server: kill $PHP_SERVER_PROCESS_ID From 52d352dbf762f39d7c3113606220266cdd0bad8e Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 15:18:35 +0100 Subject: [PATCH 083/270] These are all acceptance tests. --- bin/test.sh | 5 - tests/_support/AcceptanceTester.php | 124 +++++++++++++++++++++++- tests/_support/FunctionalTester.php | 141 ---------------------------- tests/acceptance/SwitchUserCest.php | 4 +- tests/functional.suite.yml | 24 ----- 5 files changed, 125 insertions(+), 173 deletions(-) delete mode 100644 tests/_support/FunctionalTester.php delete mode 100644 tests/functional.suite.yml diff --git a/bin/test.sh b/bin/test.sh index 4d174e4..e711ecc 100755 --- a/bin/test.sh +++ b/bin/test.sh @@ -30,11 +30,6 @@ $WP plugin activate user-switching $WP language core install it_IT $WP language plugin install user-switching it_IT -# Run the functional tests: -TEST_SITE_WP_URL=$WP_URL \ - ./vendor/bin/codecept run functional --steps "$1" \ - || ( TESTS_EXIT_CODE=$? && kill $PHP_SERVER_PROCESS_ID && exit $TESTS_EXIT_CODE ) - # Run the acceptance tests: TEST_SITE_WP_URL=$WP_URL \ ./vendor/bin/codecept run acceptance --steps "$1" \ diff --git a/tests/_support/AcceptanceTester.php b/tests/_support/AcceptanceTester.php index eb5cc43..33304d2 100644 --- a/tests/_support/AcceptanceTester.php +++ b/tests/_support/AcceptanceTester.php @@ -13,7 +13,129 @@ * @method void comment($description) * @method void pause() */ -class AcceptanceTester extends FunctionalTester { +class AcceptanceTester extends \Codeception\Actor { use _generated\AcceptanceTesterActions; + /** + * Switch to the specified user + * + * @param string $user_login + */ + public function switchToUser( $user_login ) { + $user_id = $this->grabUserIdFromDatabase( $user_login ); + + $this->amOnAdminPage( sprintf( 'user-edit.php?user_id=%d', $user_id ) ); + $this->click( '#user_switching_switcher' ); + } + + /** + * Switch off + */ + public function switchOff() { + $this->amOnAdminPage( '/' ); + $this->click( 'Switch Off' ); + } + + /** + * Switch back to the original user + * + * @param string $user_login + */ + public function switchBack( $user_login ) { + $display_name = $this->grabFromDatabase( + $this->grabUsersTableName(), + 'display_name', + [ + 'user_login' => $user_login, + ] + ); + + $this->click( sprintf( + 'Switch back to %1$s (%2$s)', + $display_name, + $user_login + ) ); + } + + /** + * Verify that the user is logged in as the specified user + * + * @param string $user_login + */ + public function loggedInAs( $user_login ) { + $display_name = $this->grabFromDatabase( + $this->grabUsersTableName(), + 'display_name', + [ + 'user_login' => $user_login, + ] + ); + + $this->see( + $display_name, + '#wpadminbar .display-name' + ); + } + + /** + * Verify that the user is logged out + */ + public function loggedOut() { + $this->cantSeeElement( '#wpadminbar .display-name' ); + } + + /** + * Verify the page language + * + * @param string $lang + */ + public function thePageLanguageShouldBe( $lang ) { + throw new \Exception( 'Not implemented' ); + } + + /** + * Verify the language of an element + * + * @param string $selector + * @param string $lang + */ + public function theElementLanguageShouldBe( $selector, $lang ) { + throw new \Exception( 'Not implemented' ); + } + + /** + * Checks that the current page contains an admin success notice. + * + * @param string $text The message text to search for. + */ + public function seeAdminSuccessNotice( string $text ) { + return $this->see( $text, '.notice-success' ); + } + + /** + * Checks that the current page contains an admin success notice. + * + * @param string $text The message text to search for. + */ + public function seeAdminWarningNotice( string $text ) { + return $this->see( $text, '.notice-warning' ); + } + + /** + * Checks that the current page contains an admin success notice. + * + * @param string $text The message text to search for. + */ + public function seeAdminErrorNotice( string $text ) { + return $this->see( $text, '.notice-error' ); + } + + /** + * Checks that the current page contains an admin success notice. + * + * @param string $text The message text to search for. + */ + public function seeAdminInfoNotice( string $text ) { + return $this->see( $text, '.notice-info' ); + } } diff --git a/tests/_support/FunctionalTester.php b/tests/_support/FunctionalTester.php deleted file mode 100644 index fbae7df..0000000 --- a/tests/_support/FunctionalTester.php +++ /dev/null @@ -1,141 +0,0 @@ -grabUserIdFromDatabase( $user_login ); - - $this->amOnAdminPage( sprintf( 'user-edit.php?user_id=%d', $user_id ) ); - $this->click( '#user_switching_switcher' ); - } - - /** - * Switch off - */ - public function switchOff() { - $this->amOnAdminPage( '/' ); - $this->click( 'Switch Off' ); - } - - /** - * Switch back to the original user - * - * @param string $user_login - */ - public function switchBack( $user_login ) { - $display_name = $this->grabFromDatabase( - $this->grabUsersTableName(), - 'display_name', - [ - 'user_login' => $user_login, - ] - ); - - $this->click( sprintf( - 'Switch back to %1$s (%2$s)', - $display_name, - $user_login - ) ); - } - - /** - * Verify that the user is logged in as the specified user - * - * @param string $user_login - */ - public function loggedInAs( $user_login ) { - $display_name = $this->grabFromDatabase( - $this->grabUsersTableName(), - 'display_name', - [ - 'user_login' => $user_login, - ] - ); - - $this->see( - $display_name, - '#wpadminbar .display-name' - ); - } - - /** - * Verify that the user is logged out - */ - public function loggedOut() { - $this->cantSeeElement( '#wpadminbar .display-name' ); - } - - /** - * Verify the page language - * - * @param string $lang - */ - public function thePageLanguageShouldBe( $lang ) { - throw new \Exception( 'Not implemented' ); - } - - /** - * Verify the language of an element - * - * @param string $selector - * @param string $lang - */ - public function theElementLanguageShouldBe( $selector, $lang ) { - throw new \Exception( 'Not implemented' ); - } - - /** - * Checks that the current page contains an admin success notice. - * - * @param string $text The message text to search for. - */ - public function seeAdminSuccessNotice( string $text ) { - return $this->see( $text, '.notice-success' ); - } - - /** - * Checks that the current page contains an admin success notice. - * - * @param string $text The message text to search for. - */ - public function seeAdminWarningNotice( string $text ) { - return $this->see( $text, '.notice-warning' ); - } - - /** - * Checks that the current page contains an admin success notice. - * - * @param string $text The message text to search for. - */ - public function seeAdminErrorNotice( string $text ) { - return $this->see( $text, '.notice-error' ); - } - - /** - * Checks that the current page contains an admin success notice. - * - * @param string $text The message text to search for. - */ - public function seeAdminInfoNotice( string $text ) { - return $this->see( $text, '.notice-info' ); - } -} diff --git a/tests/acceptance/SwitchUserCest.php b/tests/acceptance/SwitchUserCest.php index 3cea12f..6125ac9 100644 --- a/tests/acceptance/SwitchUserCest.php +++ b/tests/acceptance/SwitchUserCest.php @@ -1,12 +1,12 @@ comment( 'As an administrator' ); $I->comment( 'I need to be able to switch between users' ); diff --git a/tests/functional.suite.yml b/tests/functional.suite.yml deleted file mode 100644 index 4bd5f4e..0000000 --- a/tests/functional.suite.yml +++ /dev/null @@ -1,24 +0,0 @@ -# Codeception Test Suite Configuration -# -# Suite for functional tests -# Perform tests in browser using WPBrowser. - -actor: FunctionalTester -modules: - enabled: - - WPDb - - WPBrowser - config: - WPDb: - dsn: 'mysql:host=%WP_TESTS_DB_HOST%;dbname=%WP_TESTS_DB_NAME%' - user: '%WP_TESTS_DB_USER%' - password: '%WP_TESTS_DB_PASS%' - url: '%TEST_SITE_WP_URL%' - dump: false - populate: false - cleanup: false - WPBrowser: - url: '%TEST_SITE_WP_URL%' - adminUsername: 'admin' - adminPassword: 'admin' - adminPath: '/wp-admin' From 183b381c5869551e8682a3841820c9add2ed754b Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 15:19:11 +0100 Subject: [PATCH 084/270] This is complete. --- features/switch-user.feature | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 features/switch-user.feature diff --git a/features/switch-user.feature b/features/switch-user.feature deleted file mode 100644 index 770d2d1..0000000 --- a/features/switch-user.feature +++ /dev/null @@ -1,29 +0,0 @@ -Feature: Switch users - As an administrator - I need to be able to switch between users - In order to access different user accounts - - Background: - Given the "user-switching/user-switching.php" plugin is active - And there are users: - | user_login | display_name | user_email | user_pass | role | - | editor | Editor | editor@example.com | password | editor | - - Scenario: Switch to editor and back - Given I am logged in as admin - When I switch to user "editor" - Then I should see a status message that says "Switched to editor" - And I should be logged in as "editor" - - When I go to the dashboard - And I switch back to "admin" - Then I should see a status message that says "Switched back to admin" - And I should be logged in as "admin" - - Scenario: Switch off and back - Given I am logged in as admin - When I switch off - Then I should be logged out - - When I switch back to "admin" - Then I should be logged in as "admin" From b3dc8cc7e5d7470eed29182e41a1be9570a8bb9d Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 15:35:55 +0100 Subject: [PATCH 085/270] Better job names. --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ff67615..41ed2e3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,7 +34,7 @@ jobs: php: ['8.0','7.3'] wp: ['*', 'dev-nightly'] fail-fast: false - name: WP ${{ matrix.wp }} / PHP ${{ matrix.php }} + name: "WP ${{ matrix.wp == '*' ? 'latest' : matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 timeout-minutes: 10 steps: From 110e54670e08a4c4c2f685fca5f9541fe114019e Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 15:36:11 +0100 Subject: [PATCH 086/270] Upload test artifacts. --- .github/workflows/test.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 41ed2e3..9762cb9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -78,3 +78,10 @@ jobs: - name: Run the tests run: composer test:ut + + - name: Upload test artifacts + if: failure() + uses: actions/upload-artifact@v2 + with: + name: "test-wp-${{ matrix.wp == '*' ? 'latest' : matrix.wp }}-php-${{ matrix.php }}" + path: tests/_output From 2cd66608eca8c511da48fa28babccfd1d2e97ab6 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 15:39:39 +0100 Subject: [PATCH 087/270] More CI fixes. --- .github/workflows/e2e.yml | 9 ++++++++- .github/workflows/test.yml | 7 ------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 9440ba0..ad56264 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -36,7 +36,7 @@ jobs: php: ['8.0','7.4'] wp: ['*', 'dev-nightly'] fail-fast: false - name: WP ${{ matrix.wp }} / PHP ${{ matrix.php }} + name: "WP ${{ matrix.wp == '*' ? 'latest' : matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 timeout-minutes: 10 steps: @@ -81,3 +81,10 @@ jobs: run: composer test:ft env: WP_TESTS_DB_PASS: root + + - name: Upload test artifacts + if: failure() + uses: actions/upload-artifact@v2 + with: + name: "test-wp-${{ matrix.wp == '*' ? 'latest' : matrix.wp }}-php-${{ matrix.php }}" + path: tests/_output diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9762cb9..41ed2e3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -78,10 +78,3 @@ jobs: - name: Run the tests run: composer test:ut - - - name: Upload test artifacts - if: failure() - uses: actions/upload-artifact@v2 - with: - name: "test-wp-${{ matrix.wp == '*' ? 'latest' : matrix.wp }}-php-${{ matrix.php }}" - path: tests/_output From 4dc932184dafdefb273b41777c3b2a093ddfe336 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 15:39:45 +0100 Subject: [PATCH 088/270] More tests. --- tests/acceptance/SwitchFromEnglishCest.php | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 tests/acceptance/SwitchFromEnglishCest.php diff --git a/tests/acceptance/SwitchFromEnglishCest.php b/tests/acceptance/SwitchFromEnglishCest.php new file mode 100644 index 0000000..f69a221 --- /dev/null +++ b/tests/acceptance/SwitchFromEnglishCest.php @@ -0,0 +1,42 @@ +comment( 'As an administrator of a site which uses more than one language' ); + $I->comment( 'I need to be able to switch to user accounts that use a different language' ); + $I->comment( 'And see the output of User Switching in my original language' ); + + $I->haveUserInDatabase( 'autore', 'author', [ + 'display_name' => 'Autore', + 'locale' => 'it_IT', + ] ); + } + + public function SwitchFromEnglishAdminToItalianAuthorAndBack( AcceptanceTester $I ) { + // Given I am logged in as admin + $I->loginAsAdmin(); + // When I switch to user "autore" + $I->switchToUser( 'autore' ); + // Then the page language should be "it-IT" + $I->thePageLanguageShouldBe( 'it-IT' ); + // But I should see a status message that says "Switched to Autore" + $I->seeAdminSuccessNotice( 'Switched to Autore' ); + // And the "#user_switching p" element language should be "en-US" + // @TODO + + // When I go to the dashboard + $I->amOnAdminPage( '/' ); + // And I switch back to "admin" + $I->switchBack( 'admin' ); + // Then the page language should be "en-US" + $I->thePageLanguageShouldBe( 'en-US' ); + // And I should see a status message that says "Switched back to admin" + $I->seeAdminSuccessNotice( 'Switched back to admin' ); + } +} From 493a5969ea68ebc14f4580bc7015fe88bc6d406e Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 15:44:40 +0100 Subject: [PATCH 089/270] Switch to GHA flavour ternaries. --- .github/workflows/e2e.yml | 4 ++-- .github/workflows/test.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index ad56264..164a5ef 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -36,7 +36,7 @@ jobs: php: ['8.0','7.4'] wp: ['*', 'dev-nightly'] fail-fast: false - name: "WP ${{ matrix.wp == '*' ? 'latest' : matrix.wp }} / PHP ${{ matrix.php }}" + name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 timeout-minutes: 10 steps: @@ -86,5 +86,5 @@ jobs: if: failure() uses: actions/upload-artifact@v2 with: - name: "test-wp-${{ matrix.wp == '*' ? 'latest' : matrix.wp }}-php-${{ matrix.php }}" + name: "test-wp-${{ matrix.wp == '*' && 'latest' || matrix.wp }}-php-${{ matrix.php }}" path: tests/_output diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 41ed2e3..5459bf5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,7 +34,7 @@ jobs: php: ['8.0','7.3'] wp: ['*', 'dev-nightly'] fail-fast: false - name: "WP ${{ matrix.wp == '*' ? 'latest' : matrix.wp }} / PHP ${{ matrix.php }}" + name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 timeout-minutes: 10 steps: From ad98477680e1ff433ba602fc97fabdfdab851c79 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 15:58:26 +0100 Subject: [PATCH 090/270] Update WPBrowser so we don't need the patch. --- composer.json | 9 +-------- tests/patches/wp-browser.patch | 25 ------------------------- tests/wpunit.suite.yml | 1 + 3 files changed, 2 insertions(+), 33 deletions(-) delete mode 100644 tests/patches/wp-browser.patch diff --git a/composer.json b/composer.json index b71f89d..0e87a55 100644 --- a/composer.json +++ b/composer.json @@ -20,17 +20,11 @@ "allow-plugins": { "composer/installers": true, "composer/package-versions-deprecated": true, - "cweagans/composer-patches": true, "dealerdirect/phpcodesniffer-composer-installer": true, "roots/wordpress-core-installer": true } }, "extra": { - "patches": { - "lucatume/wp-browser": { - "Remove pluggable function definitions": "tests/patches/wp-browser.patch" - } - }, "wordpress-install-dir": "tests/wordpress" }, "require": { @@ -42,8 +36,7 @@ "dealerdirect/phpcodesniffer-composer-installer": "*", "genesis/behat-fail-aid": "^2.0", "johnbillion/wordhat": "dev-develop", - "cweagans/composer-patches": "^1.7", - "lucatume/wp-browser": "3.0.17", + "lucatume/wp-browser": "^3.0", "phpcompatibility/php-compatibility": "^9", "phpstan/phpstan": "^1.0", "phpstan/phpstan-deprecation-rules": "^1.0", diff --git a/tests/patches/wp-browser.patch b/tests/patches/wp-browser.patch deleted file mode 100644 index 5e004ef..0000000 --- a/tests/patches/wp-browser.patch +++ /dev/null @@ -1,25 +0,0 @@ -diff --git a/src/includes/functions.php b/src/includes/functions.php -index 235a9519..178d630a 100644 ---- a/src/includes/functions.php -+++ b/src/includes/functions.php -@@ -196,20 +196,3 @@ function _upload_dir_https($uploads) - - return $uploads; - } -- --if (! function_exists('wp_set_auth_cookie') && ! function_exists('wp_clear_auth_cookie')) { -- // No `setcookie` calls to avoid: "Cannot modify header information - headers already sent" -- function wp_set_auth_cookie($user_id, $remember = false, $secure = '', $token = '') -- { -- /** This action is documented in wp-inclues/pluggable.php */ -- do_action('set_auth_cookie', null, null, null, $user_id, null); -- /** This action is documented in wp-inclues/pluggable.php */ -- do_action('set_logged_in_cookie', null, null, null, $user_id, 'logged_in'); -- } -- -- function wp_clear_auth_cookie() -- { -- /** This action is documented in wp-inclues/pluggable.php */ -- do_action('clear_auth_cookie'); -- } --} diff --git a/tests/wpunit.suite.yml b/tests/wpunit.suite.yml index e261be7..5d9474a 100644 --- a/tests/wpunit.suite.yml +++ b/tests/wpunit.suite.yml @@ -14,6 +14,7 @@ modules: dbHost: "%WP_TESTS_DB_HOST%" dbUser: "%WP_TESTS_DB_USER%" dbPassword: "%WP_TESTS_DB_PASS%" + skipPluggables: true plugins: ['user-switching/user-switching.php'] activatePlugins: ['user-switching/user-switching.php'] env: From 363102f02ec1978e73fe7ad36fcefd31719351c8 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 15:58:43 +0100 Subject: [PATCH 091/270] More removals. --- .github/workflows/test.yml | 6 +++--- tests/stubs.php | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ff67615..28d91d6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ on: paths: - '.github/workflows/test.yml' - 'composer.json' - - 'phpunit.xml.dist' + - 'codeception.dist.yml' - 'tests/**' - 'user-switching.php' pull_request: @@ -19,7 +19,7 @@ on: paths: - '.github/workflows/test.yml' - 'composer.json' - - 'phpunit.xml.dist' + - 'codeception.dist.yml' - 'tests/**' - 'user-switching.php' # Once weekly on Wednesdays at 05:00 UTC. @@ -73,7 +73,7 @@ jobs: run: | sudo systemctl start mysql.service composer install --prefer-dist - composer require --dev --update-with-dependencies --prefer-dist roots/wordpress="${{ matrix.wp }} || *" wp-phpunit/wp-phpunit="${{ matrix.wp }} || *" + composer require --dev --update-with-dependencies --prefer-dist roots/wordpress="${{ matrix.wp }} || *" mysqladmin -uroot -proot create wordpress_test - name: Run the tests diff --git a/tests/stubs.php b/tests/stubs.php index 0ede72c..d20bf36 100644 --- a/tests/stubs.php +++ b/tests/stubs.php @@ -86,5 +86,3 @@ public function forget_session() {} * @return \WooCommerce */ function WC() {} - -class PHPUnit_Framework_TestCase {} From 932b4e6bd4c3e90c0265ca17e055cfb417560fcb Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 16:03:57 +0100 Subject: [PATCH 092/270] This may as well use 7.4 so the Composer cache hits. --- .github/workflows/coding-standards.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 0dc9c31..09ecde2 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -42,7 +42,7 @@ jobs: cache-name: cache-composer-dependencies with: path: ${{ steps.composer-cache.outputs.dir }} - key: 7.3-composer-${{ hashFiles('composer.json') }} + key: 7.4-composer-${{ hashFiles('composer.json') }} - name: PHPCS and PHPStan cache uses: actions/cache@v2 @@ -53,12 +53,12 @@ jobs: # This uses the hash of user-switching.php in its cache key because Actions doesn't support # always pulling in a cache file and simultaneously always updating it, unlike Travis. # This way we always pull in a cache file and refresh it with each new version of the plugin. - key: 7.3-phpcs-${{ hashFiles('user-switching.php') }} + key: 7.4-phpcs-${{ hashFiles('user-switching.php') }} - name: Install PHP uses: shivammathur/setup-php@2.7.0 with: - php-version: '7.3' + php-version: '7.4' coverage: none env: fail-fast: true From 58375c1d5cd9b985497ac3070a9e7df63d807fc9 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 16:30:46 +0100 Subject: [PATCH 093/270] Finish this test. --- tests/_support/AcceptanceTester.php | 6 ++++-- tests/acceptance/SwitchFromEnglishCest.php | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/_support/AcceptanceTester.php b/tests/_support/AcceptanceTester.php index 33304d2..60e7b80 100644 --- a/tests/_support/AcceptanceTester.php +++ b/tests/_support/AcceptanceTester.php @@ -90,7 +90,7 @@ public function loggedOut() { * @param string $lang */ public function thePageLanguageShouldBe( $lang ) { - throw new \Exception( 'Not implemented' ); + $this->theElementLanguageShouldBe( 'html', $lang ); } /** @@ -100,7 +100,9 @@ public function thePageLanguageShouldBe( $lang ) { * @param string $lang */ public function theElementLanguageShouldBe( $selector, $lang ) { - throw new \Exception( 'Not implemented' ); + $this->seeElement( $selector, [ + 'lang' => $lang, + ] ); } /** diff --git a/tests/acceptance/SwitchFromEnglishCest.php b/tests/acceptance/SwitchFromEnglishCest.php index f69a221..d77cdc9 100644 --- a/tests/acceptance/SwitchFromEnglishCest.php +++ b/tests/acceptance/SwitchFromEnglishCest.php @@ -14,7 +14,9 @@ public function _before( AcceptanceTester $I ) { $I->haveUserInDatabase( 'autore', 'author', [ 'display_name' => 'Autore', - 'locale' => 'it_IT', + 'meta' => [ + 'locale' => 'it_IT', + ], ] ); } @@ -28,7 +30,7 @@ public function SwitchFromEnglishAdminToItalianAuthorAndBack( AcceptanceTester $ // But I should see a status message that says "Switched to Autore" $I->seeAdminSuccessNotice( 'Switched to Autore' ); // And the "#user_switching p" element language should be "en-US" - // @TODO + $I->theElementLanguageShouldBe( '#user_switching p', 'en-US' ); // When I go to the dashboard $I->amOnAdminPage( '/' ); From 59483353d4c5e6d175d5bb941b98327fdd2140bb Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 16:36:38 +0100 Subject: [PATCH 094/270] More tests. --- tests/acceptance/SwitchToEnglishCest.php | 47 ++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 tests/acceptance/SwitchToEnglishCest.php diff --git a/tests/acceptance/SwitchToEnglishCest.php b/tests/acceptance/SwitchToEnglishCest.php new file mode 100644 index 0000000..f4dd762 --- /dev/null +++ b/tests/acceptance/SwitchToEnglishCest.php @@ -0,0 +1,47 @@ +comment( 'As an administrator of a site which uses more than one language' ); + $I->comment( 'I need to be able to switch between users' ); + $I->comment( 'And see the output of User Switching in my original language' ); + + $I->haveUserInDatabase( 'admin_it', 'administrator', [ + 'display_name' => 'Admin IT', + 'meta' => [ + 'locale' => 'it_IT', + ], + ] ); + $I->haveUserInDatabase( 'author_en', 'author', [ + 'display_name' => 'Author EN', + ] ); + } + + public function SwitchFromItalianAdminToEnglishAuthorAndBack( AcceptanceTester $I ) { + // Given I am logged in as admin_it + $I->loginAs( 'admin_it', 'admin_it' ); + // When I switch to user "author_en" + $I->switchToUser( 'author_en' ); + // Then the page language should be "en-US" + $I->thePageLanguageShouldBe( 'en-US' ); + // But I should see a status message that says "Cambiato a Author EN" + $I->seeAdminSuccessNotice( 'Cambiato a Author EN' ); + // And the "#user_switching p" element language should be "it-IT" + $I->theElementLanguageShouldBe( '#user_switching p', 'it-IT' ); + + // When I go to the dashboard + $I->amOnAdminPage( '/' ); + // And I switch back to "admin_it" + $I->switchBack( 'admin_it' ); + // Then the page language should be "it-IT" + $I->thePageLanguageShouldBe( 'it-IT' ); + // And I should see a status message that says "Tornato a Admin IT" + $I->seeAdminSuccessNotice( 'Tornato a Admin IT' ); + } +} From 05bd3ded3edcf9b18f9a9c4e36ebfc849da10e75 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 16:43:01 +0100 Subject: [PATCH 095/270] Update this path. --- .github/workflows/e2e.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 164a5ef..7188b36 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -12,7 +12,7 @@ on: - 'codeception.dist.yml' - 'bin/test.sh' - 'composer.json' - - 'features/**' + - 'tests/**' - 'user-switching.php' pull_request: branches: @@ -22,7 +22,7 @@ on: - 'codeception.dist.yml' - 'bin/test.sh' - 'composer.json' - - 'features/**' + - 'tests/**' - 'user-switching.php' # Once weekly on Wednesdays at 06:00 UTC. schedule: From 6277f7fa694902125ab48d801e530ec94abc4c6f Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 16:43:14 +0100 Subject: [PATCH 096/270] Remove the old feature files. --- features/bootstrap/UserSwitchingContext.php | 174 -------------------- features/locales.feature | 22 --- features/locales2.feature | 23 --- 3 files changed, 219 deletions(-) delete mode 100644 features/bootstrap/UserSwitchingContext.php delete mode 100644 features/locales.feature delete mode 100644 features/locales2.feature diff --git a/features/bootstrap/UserSwitchingContext.php b/features/bootstrap/UserSwitchingContext.php deleted file mode 100644 index 21f20e0..0000000 --- a/features/bootstrap/UserSwitchingContext.php +++ /dev/null @@ -1,174 +0,0 @@ -[^"]+)"$/ - */ - public function switch_to_user( $user_id ) { - $user_id = $this->getUserIdFromLogin( $user_id ); - - Assert::assertNotEmpty( $user_id ); - - $this->visitPath( sprintf( 'wp-admin/user-edit.php?user_id=%d', $user_id ) ); - $this->getSession()->getPage()->clickLink( 'user_switching_switcher' ); - } - - /** - * Switch off - * - * @When /^(?:|I )switch off$/ - */ - public function switch_off() { - $this->getSession()->getPage()->clickLink( "Switch Off" ); - } - - /** - * Switch back to the original user - * - * @param string $user_id - * - * @When /^(?:|I )switch back to "(?P[^"]+)"$/ - */ - public function switch_back( $user_id ) { - $display_name = $this->getUserDataFromUsername( 'display_name', $user_id ); - - Assert::assertNotEmpty( $user_id ); - Assert::assertNotEmpty( $display_name ); - - $this->getSession()->getPage()->clickLink( sprintf( - 'Switch back to %1$s (%2$s)', - $display_name, - $user_id - ) ); - } - - /** - * Verify that the user is logged in as the specified user - * - * @param string $user_id - * - * @Then /^(?:|I )should be logged in as "(?P[^"]+)"$/ - * - * @throws ElementNotFoundException If the display name could not be found. - * @throws ElementTextException If the display name is incorrect. - */ - public function logged_in_as( $user_id ) { - $display_name = $this->getUserDataFromUsername( 'display_name', $user_id ); - - Assert::assertNotEmpty( $display_name ); - - $this->visitPath( '/' ); - - $browser = $this->getSession(); - $selector = '#wpadminbar .display-name'; - $element = $browser->getPage()->find( 'css', $selector ); - - if ( ! $element ) { - throw new ElementNotFoundException( - $browser->getDriver(), - 'element', - 'css', - $selector - ); - } - - if ( $display_name !== $element->getText() ) { - throw new ElementTextException( - sprintf( - 'The user is logged in as "%s"', - $element->getText() - ), - $browser->getDriver(), - $element - ); - } - } - - /** - * Verify that the user is logged out - * - * @Then /^(?:|I )should be logged out$/ - * - * @throws ExpectationException If the user is not logged out. - */ - public function logged_out() { - $this->visitPath( '/' ); - - $browser = $this->getSession(); - $selector = '#wpadminbar .display-name'; - $element = $browser->getPage()->find( 'css', $selector ); - - if ( $element ) { - throw new ExpectationException( - 'The user is not logged out', - $browser->getDriver() - ); - } - } - - /** - * Verify the page language - * - * @param string $lang - * - * @Then /^the page language should be "(?P[^"]+)"$/ - * - * @throws ElementHtmlException If the language is incorrect. - */ - public function thePageLanguageShouldBe( $lang ) { - $this->theElementLanguageShouldBe( 'html', $lang ); - } - - /** - * Verify the language of an element - * - * @param string $selector - * @param string $lang - * - * @Then /^the "(?P[^"]+)" element language should be "(?P[^"]+)"$/ - * - * @throws ElementHtmlException If the language is incorrect. - */ - public function theElementLanguageShouldBe( $selector, $lang ) { - $browser = $this->getSession(); - $element = $browser->getPage()->find( 'css', $selector ); - - if ( ! $element ) { - throw new ElementNotFoundException( - $browser->getDriver(), - 'element', - 'css', - $selector - ); - } - - if ( $lang !== $element->getAttribute( 'lang' ) ) { - throw new ElementHtmlException( - sprintf( - 'The language is "%s" instead of "%s"', - $element->getAttribute( 'lang' ), - $lang - ), - $browser->getDriver(), - $element - ); - } - } -} diff --git a/features/locales.feature b/features/locales.feature deleted file mode 100644 index 67f2cae..0000000 --- a/features/locales.feature +++ /dev/null @@ -1,22 +0,0 @@ -Feature: Locale support - As an administrator of a site which uses more than one language - I need to be able to switch to user accounts that use a different language - And see User Switching's output in my original language - - Background: - Given the "user-switching/user-switching.php" plugin is active - And there are users: - | user_login | display_name | user_email | user_pass | role | locale | - | autore | Autore | autore@example.com | password | author | it_IT | - - Scenario: Switch from English admin to Italian author and back - Given I am logged in as admin - When I switch to user "autore" - Then the page language should be "it-IT" - But I should see a status message that says "Switched to Autore" - And the "#user_switching p" element language should be "en-US" - - When I go to the dashboard - And I switch back to "admin" - Then the page language should be "en-US" - And I should see a status message that says "Switched back to admin" diff --git a/features/locales2.feature b/features/locales2.feature deleted file mode 100644 index 5d52c5b..0000000 --- a/features/locales2.feature +++ /dev/null @@ -1,23 +0,0 @@ -Feature: Locale support - As an administrator of a site which uses more than one language - I need to be able to switch between users - And see User Switching's output in my original language - - Background: - Given the "user-switching/user-switching.php" plugin is active - And there are users: - | user_login | display_name | user_email | user_pass | role | locale | - | admin_it | Admin IT | admin_it@example.com | password | administrator | it_IT | - | author_en | Author EN | author_en@example.com | password | author | | - - Scenario: Switch from Italian admin to English author and back - Given I am logged in as admin_it - When I switch to user "author_en" - Then the page language should be "en-US" - But I should see a status message that says "Cambiato a Author EN" - And the "#user_switching p" element language should be "it-IT" - - When I go to the dashboard - And I switch back to "admin_it" - Then the page language should be "it-IT" - And I should see a status message that says "Tornato a Admin IT" From 0dc75a82cba42fe0a91b6a74558ca003590fa0f6 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 16:43:24 +0100 Subject: [PATCH 097/270] Move this into its own directory. --- phpstan.neon.dist | 2 +- tests/{ => phpstan}/stubs.php | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/{ => phpstan}/stubs.php (100%) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 76a5ee5..1d73e62 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -8,7 +8,7 @@ parameters: paths: - user-switching.php bootstrapFiles: - - tests/stubs.php + - tests/phpstan/stubs.php ignoreErrors: # Uses func_get_args() - '#^Function apply_filters invoked with [34567] parameters, 2 required\.$#' diff --git a/tests/stubs.php b/tests/phpstan/stubs.php similarity index 100% rename from tests/stubs.php rename to tests/phpstan/stubs.php From bd14f8dd1b08be2fc1e49a8b64b302b523577ef2 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 16:53:21 +0100 Subject: [PATCH 098/270] Remove redundant comments. --- tests/acceptance/SwitchFromEnglishCest.php | 12 ------------ tests/acceptance/SwitchToEnglishCest.php | 12 ------------ tests/acceptance/SwitchUserCest.php | 16 ---------------- 3 files changed, 40 deletions(-) diff --git a/tests/acceptance/SwitchFromEnglishCest.php b/tests/acceptance/SwitchFromEnglishCest.php index d77cdc9..6b32d85 100644 --- a/tests/acceptance/SwitchFromEnglishCest.php +++ b/tests/acceptance/SwitchFromEnglishCest.php @@ -3,9 +3,6 @@ * Acceptance tests for switching from a user who uses English to a user who doesn't */ -/** - * Test class. - */ class SwitchFromEnglishCest { public function _before( AcceptanceTester $I ) { $I->comment( 'As an administrator of a site which uses more than one language' ); @@ -21,24 +18,15 @@ public function _before( AcceptanceTester $I ) { } public function SwitchFromEnglishAdminToItalianAuthorAndBack( AcceptanceTester $I ) { - // Given I am logged in as admin $I->loginAsAdmin(); - // When I switch to user "autore" $I->switchToUser( 'autore' ); - // Then the page language should be "it-IT" $I->thePageLanguageShouldBe( 'it-IT' ); - // But I should see a status message that says "Switched to Autore" $I->seeAdminSuccessNotice( 'Switched to Autore' ); - // And the "#user_switching p" element language should be "en-US" $I->theElementLanguageShouldBe( '#user_switching p', 'en-US' ); - // When I go to the dashboard $I->amOnAdminPage( '/' ); - // And I switch back to "admin" $I->switchBack( 'admin' ); - // Then the page language should be "en-US" $I->thePageLanguageShouldBe( 'en-US' ); - // And I should see a status message that says "Switched back to admin" $I->seeAdminSuccessNotice( 'Switched back to admin' ); } } diff --git a/tests/acceptance/SwitchToEnglishCest.php b/tests/acceptance/SwitchToEnglishCest.php index f4dd762..c870736 100644 --- a/tests/acceptance/SwitchToEnglishCest.php +++ b/tests/acceptance/SwitchToEnglishCest.php @@ -3,9 +3,6 @@ * Acceptance tests for switching from a user who doesn't use English to a user who does */ -/** - * Test class. - */ class SwitchToEnglishCest { public function _before( AcceptanceTester $I ) { $I->comment( 'As an administrator of a site which uses more than one language' ); @@ -24,24 +21,15 @@ public function _before( AcceptanceTester $I ) { } public function SwitchFromItalianAdminToEnglishAuthorAndBack( AcceptanceTester $I ) { - // Given I am logged in as admin_it $I->loginAs( 'admin_it', 'admin_it' ); - // When I switch to user "author_en" $I->switchToUser( 'author_en' ); - // Then the page language should be "en-US" $I->thePageLanguageShouldBe( 'en-US' ); - // But I should see a status message that says "Cambiato a Author EN" $I->seeAdminSuccessNotice( 'Cambiato a Author EN' ); - // And the "#user_switching p" element language should be "it-IT" $I->theElementLanguageShouldBe( '#user_switching p', 'it-IT' ); - // When I go to the dashboard $I->amOnAdminPage( '/' ); - // And I switch back to "admin_it" $I->switchBack( 'admin_it' ); - // Then the page language should be "it-IT" $I->thePageLanguageShouldBe( 'it-IT' ); - // And I should see a status message that says "Tornato a Admin IT" $I->seeAdminSuccessNotice( 'Tornato a Admin IT' ); } } diff --git a/tests/acceptance/SwitchUserCest.php b/tests/acceptance/SwitchUserCest.php index 6125ac9..f14985c 100644 --- a/tests/acceptance/SwitchUserCest.php +++ b/tests/acceptance/SwitchUserCest.php @@ -3,9 +3,6 @@ * Acceptance tests for switching users. */ -/** - * Test class. - */ class SwitchUserCest { public function _before( AcceptanceTester $I ) { $I->comment( 'As an administrator' ); @@ -16,36 +13,23 @@ public function _before( AcceptanceTester $I ) { } public function SwitchToEditorAndBack( AcceptanceTester $I ) { - // Given I am logged in as admin $I->loginAsAdmin(); - // When I switch to user "editor" $I->switchToUser( 'editor' ); - // Then I should see a status message that says "Switched to editor" $I->seeAdminSuccessNotice( 'Switched to editor' ); - // And I should be logged in as "editor" $I->loggedInAs( 'editor' ); - // When I go to the dashboard $I->amOnAdminPage( '/' ); - // And I switch back to "admin" $I->switchBack( 'admin' ); - // Then I should see a status message that says "Switched back to admin" $I->seeAdminSuccessNotice( 'Switched back to admin' ); - // And I should be logged in as "admin" $I->loggedInAs( 'admin' ); } public function SwitchOffAndBack( AcceptanceTester $I ) { - // Given I am logged in as admin $I->loginAsAdmin(); - // When I switch off $I->switchOff(); - // Then I should be logged out $I->loggedOut(); - // When I switch back to "admin" $I->switchBack( 'admin' ); - // Then I should be logged in as "admin" $I->loggedInAs( 'admin' ); } } From 3e3e02b1224cf59f5ce6789665b1b3329476e970 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 16:57:47 +0100 Subject: [PATCH 099/270] Remove more old references. --- .distignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.distignore b/.distignore index 8e8ce8f..70805e0 100644 --- a/.distignore +++ b/.distignore @@ -3,7 +3,6 @@ .github .wordpress-org bin -features node_modules tests vendor @@ -15,7 +14,6 @@ codeception.dist.yml composer.json composer.lock CONTRIBUTING.md -Gruntfile.js package-lock.json package.json phpcs.xml.dist From d88836c52f3443b223c96f7b9e5e94b5b38f9c43 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 17:16:31 +0100 Subject: [PATCH 100/270] Move the WP-CLI setup steps into the test runner. --- bin/test.sh | 16 ---------------- composer.json | 1 + tests/acceptance.suite.yml | 4 ++++ tests/acceptance/Cest.php | 20 ++++++++++++++++++++ tests/acceptance/SwitchFromEnglishCest.php | 4 +++- tests/acceptance/SwitchToEnglishCest.php | 4 +++- tests/acceptance/SwitchUserCest.php | 4 +++- 7 files changed, 34 insertions(+), 19 deletions(-) create mode 100644 tests/acceptance/Cest.php diff --git a/bin/test.sh b/bin/test.sh index e711ecc..fbe77ee 100755 --- a/bin/test.sh +++ b/bin/test.sh @@ -10,26 +10,10 @@ WP_CORE_DIR="${PWD}/tests/wordpress" # Specify the URL for the site: WP_URL="localhost:8000" -# Shorthand: -WP="./vendor/bin/wp --color --path=$WP_CORE_DIR --url=http://$WP_URL" - # Start the PHP server: php -S "$WP_URL" -t "$WP_CORE_DIR" -d disable_functions=mail 2>/dev/null & PHP_SERVER_PROCESS_ID=$! -# Reset or install the test database: -$WP db reset --yes - -# Install WordPress: -$WP core install --title="Example" --admin_user="admin" --admin_password="admin" --admin_email="admin@example.com" --skip-email - -# Activate the plugin: -$WP plugin activate user-switching - -# Install language files: -$WP language core install it_IT -$WP language plugin install user-switching it_IT - # Run the acceptance tests: TEST_SITE_WP_URL=$WP_URL \ ./vendor/bin/codecept run acceptance --steps "$1" \ diff --git a/composer.json b/composer.json index e7ca880..ca8219f 100644 --- a/composer.json +++ b/composer.json @@ -32,6 +32,7 @@ "composer/installers": "^1 || ^2" }, "require-dev": { + "codeception/module-cli": "^1.0", "codeception/module-db": "^1.0", "codeception/module-phpbrowser": "^1.0", "dealerdirect/phpcodesniffer-composer-installer": "*", diff --git a/tests/acceptance.suite.yml b/tests/acceptance.suite.yml index a349e4d..1bbe6f1 100644 --- a/tests/acceptance.suite.yml +++ b/tests/acceptance.suite.yml @@ -7,6 +7,7 @@ actor: AcceptanceTester modules: enabled: - WPDb + - WPCLI - WPBrowser config: WPDb: @@ -17,6 +18,9 @@ modules: dump: false populate: false cleanup: false + WPCLI: + path: tests/wordpress + url: '%TEST_SITE_WP_URL%' WPBrowser: url: '%TEST_SITE_WP_URL%' adminUsername: 'admin' diff --git a/tests/acceptance/Cest.php b/tests/acceptance/Cest.php new file mode 100644 index 0000000..5450c40 --- /dev/null +++ b/tests/acceptance/Cest.php @@ -0,0 +1,20 @@ +cli( 'db reset --yes' ); + + # Install WordPress: + $I->cli( 'core install --title="Example" --admin_user="admin" --admin_password="admin" --admin_email="admin@example.com" --skip-email' ); + + # Activate the plugin: + $I->cli( 'plugin activate user-switching' ); + + # Install language files: + $I->cli( 'language core install it_IT' ); + $I->cli( 'language plugin install user-switching it_IT' ); + } +} diff --git a/tests/acceptance/SwitchFromEnglishCest.php b/tests/acceptance/SwitchFromEnglishCest.php index 6b32d85..deec23d 100644 --- a/tests/acceptance/SwitchFromEnglishCest.php +++ b/tests/acceptance/SwitchFromEnglishCest.php @@ -3,8 +3,10 @@ * Acceptance tests for switching from a user who uses English to a user who doesn't */ -class SwitchFromEnglishCest { +class SwitchFromEnglishCest extends Cest { public function _before( AcceptanceTester $I ) { + parent::_before( $I ); + $I->comment( 'As an administrator of a site which uses more than one language' ); $I->comment( 'I need to be able to switch to user accounts that use a different language' ); $I->comment( 'And see the output of User Switching in my original language' ); diff --git a/tests/acceptance/SwitchToEnglishCest.php b/tests/acceptance/SwitchToEnglishCest.php index c870736..cc035eb 100644 --- a/tests/acceptance/SwitchToEnglishCest.php +++ b/tests/acceptance/SwitchToEnglishCest.php @@ -3,8 +3,10 @@ * Acceptance tests for switching from a user who doesn't use English to a user who does */ -class SwitchToEnglishCest { +class SwitchToEnglishCest extends Cest { public function _before( AcceptanceTester $I ) { + parent::_before( $I ); + $I->comment( 'As an administrator of a site which uses more than one language' ); $I->comment( 'I need to be able to switch between users' ); $I->comment( 'And see the output of User Switching in my original language' ); diff --git a/tests/acceptance/SwitchUserCest.php b/tests/acceptance/SwitchUserCest.php index f14985c..8451bb2 100644 --- a/tests/acceptance/SwitchUserCest.php +++ b/tests/acceptance/SwitchUserCest.php @@ -3,8 +3,10 @@ * Acceptance tests for switching users. */ -class SwitchUserCest { +class SwitchUserCest extends Cest { public function _before( AcceptanceTester $I ) { + parent::_before( $I ); + $I->comment( 'As an administrator' ); $I->comment( 'I need to be able to switch between users' ); $I->comment( 'In order to access different user accounts' ); From 1f381fff00ad29bedeba79756f76740887dec951 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 17:19:19 +0100 Subject: [PATCH 101/270] More config juggling. --- bin/test.sh | 1 + codeception.dist.yml | 2 +- tests/acceptance.suite.yml | 2 +- tests/wpunit.suite.yml | 12 ++++++------ 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/bin/test.sh b/bin/test.sh index fbe77ee..779f8d9 100755 --- a/bin/test.sh +++ b/bin/test.sh @@ -15,6 +15,7 @@ php -S "$WP_URL" -t "$WP_CORE_DIR" -d disable_functions=mail 2>/dev/null & PHP_SERVER_PROCESS_ID=$! # Run the acceptance tests: +TEST_SITE_WP_DIR=$WP_CORE_DIR \ TEST_SITE_WP_URL=$WP_URL \ ./vendor/bin/codecept run acceptance --steps "$1" \ || ( TESTS_EXIT_CODE=$? && kill $PHP_SERVER_PROCESS_ID && exit $TESTS_EXIT_CODE ) diff --git a/codeception.dist.yml b/codeception.dist.yml index 31e5659..0dfd4ea 100644 --- a/codeception.dist.yml +++ b/codeception.dist.yml @@ -13,6 +13,6 @@ extensions: tad\WPBrowser\Extension\Symlinker: mode: plugin destination: - default: tests/wordpress/wp-content/plugins + default: '%TEST_SITE_WP_DIR%/wp-content/plugins' params: - tests/.env diff --git a/tests/acceptance.suite.yml b/tests/acceptance.suite.yml index 1bbe6f1..cae3918 100644 --- a/tests/acceptance.suite.yml +++ b/tests/acceptance.suite.yml @@ -19,7 +19,7 @@ modules: populate: false cleanup: false WPCLI: - path: tests/wordpress + path: '%TEST_SITE_WP_DIR%' url: '%TEST_SITE_WP_URL%' WPBrowser: url: '%TEST_SITE_WP_URL%' diff --git a/tests/wpunit.suite.yml b/tests/wpunit.suite.yml index 5d9474a..821880b 100644 --- a/tests/wpunit.suite.yml +++ b/tests/wpunit.suite.yml @@ -8,12 +8,12 @@ modules: - WPLoader config: WPLoader: - wpRootFolder: "tests/wordpress" - configFile: "vendor/autoload.php" - dbName: "%WP_TESTS_DB_NAME%" - dbHost: "%WP_TESTS_DB_HOST%" - dbUser: "%WP_TESTS_DB_USER%" - dbPassword: "%WP_TESTS_DB_PASS%" + wpRootFolder: '%TEST_SITE_WP_DIR%' + configFile: 'vendor/autoload.php' + dbName: '%WP_TESTS_DB_NAME%' + dbHost: '%WP_TESTS_DB_HOST%' + dbUser: '%WP_TESTS_DB_USER%' + dbPassword: '%WP_TESTS_DB_PASS%' skipPluggables: true plugins: ['user-switching/user-switching.php'] activatePlugins: ['user-switching/user-switching.php'] From 64fdeb3efcbb5a75db34f3599a41e67ebd0f36e4 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 17:22:28 +0100 Subject: [PATCH 102/270] Create the database before running the functional tests. --- .github/workflows/e2e.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 7188b36..db322b3 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -76,6 +76,7 @@ jobs: sudo systemctl start mysql.service composer install --prefer-dist composer require --dev --update-with-dependencies --prefer-dist roots/wordpress="${{ matrix.wp }} || *" + mysqladmin -uroot -proot create wordpress_test - name: Run the tests run: composer test:ft From cfc86705e3780d23875426a4a46b8cddb67a9de3 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 17:25:18 +0100 Subject: [PATCH 103/270] These environment vars aren't available to the unit tests. --- codeception.dist.yml | 2 +- tests/wpunit.suite.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/codeception.dist.yml b/codeception.dist.yml index 0dfd4ea..31e5659 100644 --- a/codeception.dist.yml +++ b/codeception.dist.yml @@ -13,6 +13,6 @@ extensions: tad\WPBrowser\Extension\Symlinker: mode: plugin destination: - default: '%TEST_SITE_WP_DIR%/wp-content/plugins' + default: tests/wordpress/wp-content/plugins params: - tests/.env diff --git a/tests/wpunit.suite.yml b/tests/wpunit.suite.yml index 821880b..c8ee293 100644 --- a/tests/wpunit.suite.yml +++ b/tests/wpunit.suite.yml @@ -8,7 +8,7 @@ modules: - WPLoader config: WPLoader: - wpRootFolder: '%TEST_SITE_WP_DIR%' + wpRootFolder: tests/wordpress configFile: 'vendor/autoload.php' dbName: '%WP_TESTS_DB_NAME%' dbHost: '%WP_TESTS_DB_HOST%' From 6d682fdf8870eb22a0fe42b5e360f740e00b4c77 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 18:10:51 +0100 Subject: [PATCH 104/270] Terminology improvements. --- .github/workflows/coding-standards.yml | 4 ++-- .github/workflows/e2e.yml | 8 +++----- .github/workflows/test.yml | 4 ++-- CONTRIBUTING.md | 12 +++++------ composer.json | 20 +++++++++++-------- ...wpunit.suite.yml => integration.suite.yml} | 0 tests/{wpunit => integration}/Test.php | 0 tests/{wpunit => integration}/authTest.php | 0 tests/{wpunit => integration}/capsTest.php | 0 tests/{wpunit => integration}/pluginTest.php | 0 .../{wpunit => integration}/sessionsTest.php | 0 .../{wpunit => integration}/switchingTest.php | 0 12 files changed, 25 insertions(+), 23 deletions(-) rename tests/{wpunit.suite.yml => integration.suite.yml} (100%) rename tests/{wpunit => integration}/Test.php (100%) rename tests/{wpunit => integration}/authTest.php (100%) rename tests/{wpunit => integration}/capsTest.php (100%) rename tests/{wpunit => integration}/pluginTest.php (100%) rename tests/{wpunit => integration}/sessionsTest.php (100%) rename tests/{wpunit => integration}/switchingTest.php (100%) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 09ecde2..4c3f109 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -69,7 +69,7 @@ jobs: composer --version - name: Validate composer.json - run: composer validate --strict --no-check-lock + run: composer test:composer - name: Install dependencies run: | @@ -77,5 +77,5 @@ jobs: - name: Run the tests run: | - composer test:cs + composer test:phpcs composer test:phpstan diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index db322b3..0fea596 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -1,6 +1,6 @@ # yaml-language-server: $schema=https://json.schemastore.org/github-workflow -name: Functional Tests +name: Acceptance Tests on: push: branches: @@ -79,13 +79,11 @@ jobs: mysqladmin -uroot -proot create wordpress_test - name: Run the tests - run: composer test:ft - env: - WP_TESTS_DB_PASS: root + run: composer test:acceptance - name: Upload test artifacts if: failure() uses: actions/upload-artifact@v2 with: - name: "test-wp-${{ matrix.wp == '*' && 'latest' || matrix.wp }}-php-${{ matrix.php }}" + name: "acceptance-wp-${{ matrix.wp == '*' && 'latest' || matrix.wp }}-php-${{ matrix.php }}" path: tests/_output diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 50e3d52..105a3f6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,6 +1,6 @@ # yaml-language-server: $schema=https://json.schemastore.org/github-workflow -name: Unit Tests +name: Integration Tests on: push: branches: @@ -77,4 +77,4 @@ jobs: mysqladmin -uroot -proot create wordpress_test - name: Run the tests - run: composer test:ut + run: composer test:integration diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d8bbf1f..ddfe09f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -58,21 +58,21 @@ To run the whole test suite: composer test -To run just the unit tests: +To run just the integration tests: - composer test:ut + composer test:integration -To run just the code sniffs: +To run just the coding standards checks: - composer test:cs + composer test:phpcs To run just the static analysis: composer test:phpstan -To run just the functional tests: +To run just the acceptance tests: - composer test:ft + composer test:acceptance ## Releasing a New Version diff --git a/composer.json b/composer.json index ca8219f..bd0436b 100644 --- a/composer.json +++ b/composer.json @@ -60,24 +60,28 @@ "post-update-cmd": [ "@php -r \"! file_exists( 'tests/.env' ) && copy( 'tests/.env.dist', 'tests/.env' );\"" ], - "test:cs": [ + "test:phpcs": [ "phpcs -nps --colors --report-code --report-summary --report-width=80 --cache=tests/cache/phpcs.json ." ], "test:phpstan": [ "phpstan analyze" ], - "test:ut": [ - "codecept run wpunit --env singlesite --skip-group ms-required", - "codecept run wpunit --env multisite --skip-group ms-excluded" + "test:integration": [ + "codecept run integration --env singlesite --skip-group ms-required", + "codecept run integration --env multisite --skip-group ms-excluded" ], - "test:ft": [ + "test:acceptance": [ "bin/test.sh" ], + "test:composer": [ + "@composer validate --strict --no-check-lock" + ], "test": [ - "@test:cs", + "@test:composer", + "@test:phpcs", "@test:phpstan", - "@test:ut", - "@test:ft" + "@test:integration", + "@test:acceptance" ] }, "funding": [ diff --git a/tests/wpunit.suite.yml b/tests/integration.suite.yml similarity index 100% rename from tests/wpunit.suite.yml rename to tests/integration.suite.yml diff --git a/tests/wpunit/Test.php b/tests/integration/Test.php similarity index 100% rename from tests/wpunit/Test.php rename to tests/integration/Test.php diff --git a/tests/wpunit/authTest.php b/tests/integration/authTest.php similarity index 100% rename from tests/wpunit/authTest.php rename to tests/integration/authTest.php diff --git a/tests/wpunit/capsTest.php b/tests/integration/capsTest.php similarity index 100% rename from tests/wpunit/capsTest.php rename to tests/integration/capsTest.php diff --git a/tests/wpunit/pluginTest.php b/tests/integration/pluginTest.php similarity index 100% rename from tests/wpunit/pluginTest.php rename to tests/integration/pluginTest.php diff --git a/tests/wpunit/sessionsTest.php b/tests/integration/sessionsTest.php similarity index 100% rename from tests/wpunit/sessionsTest.php rename to tests/integration/sessionsTest.php diff --git a/tests/wpunit/switchingTest.php b/tests/integration/switchingTest.php similarity index 100% rename from tests/wpunit/switchingTest.php rename to tests/integration/switchingTest.php From ef79e00da5f0b6e24ff7546995d644b6ed65fb6c Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 18:25:48 +0100 Subject: [PATCH 105/270] We can go to PHPStan level 9 because `mixed` isn't used anywhere. --- phpstan.neon.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 1d73e62..b48d3d9 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -3,7 +3,7 @@ includes: - vendor/phpstan/phpstan-phpunit/extension.neon - vendor/szepeviktor/phpstan-wordpress/extension.neon parameters: - level: 8 + level: 9 tmpDir: tests/cache paths: - user-switching.php From a44b2285808a5fad1f9e0993efc41e2eb780e76d Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 18:32:58 +0100 Subject: [PATCH 106/270] More terminology improvements. --- tests/_support/AcceptanceTester.php | 10 +++++----- tests/acceptance/SwitchFromEnglishCest.php | 6 +++--- tests/acceptance/SwitchToEnglishCest.php | 6 +++--- tests/acceptance/SwitchUserCest.php | 8 ++++---- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/_support/AcceptanceTester.php b/tests/_support/AcceptanceTester.php index 60e7b80..d8898f6 100644 --- a/tests/_support/AcceptanceTester.php +++ b/tests/_support/AcceptanceTester.php @@ -62,7 +62,7 @@ public function switchBack( $user_login ) { * * @param string $user_login */ - public function loggedInAs( $user_login ) { + public function amLoggedInAs( $user_login ) { $display_name = $this->grabFromDatabase( $this->grabUsersTableName(), 'display_name', @@ -80,7 +80,7 @@ public function loggedInAs( $user_login ) { /** * Verify that the user is logged out */ - public function loggedOut() { + public function amLoggedOut() { $this->cantSeeElement( '#wpadminbar .display-name' ); } @@ -89,8 +89,8 @@ public function loggedOut() { * * @param string $lang */ - public function thePageLanguageShouldBe( $lang ) { - $this->theElementLanguageShouldBe( 'html', $lang ); + public function canSeeThePageInLanguage( $lang ) { + $this->canSeeTheElementInLanguage( 'html', $lang ); } /** @@ -99,7 +99,7 @@ public function thePageLanguageShouldBe( $lang ) { * @param string $selector * @param string $lang */ - public function theElementLanguageShouldBe( $selector, $lang ) { + public function canSeeTheElementInLanguage( $selector, $lang ) { $this->seeElement( $selector, [ 'lang' => $lang, ] ); diff --git a/tests/acceptance/SwitchFromEnglishCest.php b/tests/acceptance/SwitchFromEnglishCest.php index deec23d..45d8c4c 100644 --- a/tests/acceptance/SwitchFromEnglishCest.php +++ b/tests/acceptance/SwitchFromEnglishCest.php @@ -22,13 +22,13 @@ public function _before( AcceptanceTester $I ) { public function SwitchFromEnglishAdminToItalianAuthorAndBack( AcceptanceTester $I ) { $I->loginAsAdmin(); $I->switchToUser( 'autore' ); - $I->thePageLanguageShouldBe( 'it-IT' ); + $I->canSeeThePageInLanguage( 'it-IT' ); $I->seeAdminSuccessNotice( 'Switched to Autore' ); - $I->theElementLanguageShouldBe( '#user_switching p', 'en-US' ); + $I->canSeeTheElementInLanguage( '#user_switching p', 'en-US' ); $I->amOnAdminPage( '/' ); $I->switchBack( 'admin' ); - $I->thePageLanguageShouldBe( 'en-US' ); + $I->canSeeThePageInLanguage( 'en-US' ); $I->seeAdminSuccessNotice( 'Switched back to admin' ); } } diff --git a/tests/acceptance/SwitchToEnglishCest.php b/tests/acceptance/SwitchToEnglishCest.php index cc035eb..d374e19 100644 --- a/tests/acceptance/SwitchToEnglishCest.php +++ b/tests/acceptance/SwitchToEnglishCest.php @@ -25,13 +25,13 @@ public function _before( AcceptanceTester $I ) { public function SwitchFromItalianAdminToEnglishAuthorAndBack( AcceptanceTester $I ) { $I->loginAs( 'admin_it', 'admin_it' ); $I->switchToUser( 'author_en' ); - $I->thePageLanguageShouldBe( 'en-US' ); + $I->canSeeThePageInLanguage( 'en-US' ); $I->seeAdminSuccessNotice( 'Cambiato a Author EN' ); - $I->theElementLanguageShouldBe( '#user_switching p', 'it-IT' ); + $I->canSeeTheElementInLanguage( '#user_switching p', 'it-IT' ); $I->amOnAdminPage( '/' ); $I->switchBack( 'admin_it' ); - $I->thePageLanguageShouldBe( 'it-IT' ); + $I->canSeeThePageInLanguage( 'it-IT' ); $I->seeAdminSuccessNotice( 'Tornato a Admin IT' ); } } diff --git a/tests/acceptance/SwitchUserCest.php b/tests/acceptance/SwitchUserCest.php index 8451bb2..acd4270 100644 --- a/tests/acceptance/SwitchUserCest.php +++ b/tests/acceptance/SwitchUserCest.php @@ -18,20 +18,20 @@ public function SwitchToEditorAndBack( AcceptanceTester $I ) { $I->loginAsAdmin(); $I->switchToUser( 'editor' ); $I->seeAdminSuccessNotice( 'Switched to editor' ); - $I->loggedInAs( 'editor' ); + $I->amLoggedInAs( 'editor' ); $I->amOnAdminPage( '/' ); $I->switchBack( 'admin' ); $I->seeAdminSuccessNotice( 'Switched back to admin' ); - $I->loggedInAs( 'admin' ); + $I->amLoggedInAs( 'admin' ); } public function SwitchOffAndBack( AcceptanceTester $I ) { $I->loginAsAdmin(); $I->switchOff(); - $I->loggedOut(); + $I->amLoggedOut(); $I->switchBack( 'admin' ); - $I->loggedInAs( 'admin' ); + $I->amLoggedInAs( 'admin' ); } } From d9f87b398cf401e79204f92435881eb2397f0e59 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 5 Jan 2022 20:49:02 +0100 Subject: [PATCH 107/270] This isn't needed. --- tests/integration.suite.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration.suite.yml b/tests/integration.suite.yml index c8ee293..daa33d7 100644 --- a/tests/integration.suite.yml +++ b/tests/integration.suite.yml @@ -9,7 +9,6 @@ modules: config: WPLoader: wpRootFolder: tests/wordpress - configFile: 'vendor/autoload.php' dbName: '%WP_TESTS_DB_NAME%' dbHost: '%WP_TESTS_DB_HOST%' dbUser: '%WP_TESTS_DB_USER%' From 7b43f21b5347c4d02df1d49b9a705fbff4bdb2f2 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 01:27:14 +0100 Subject: [PATCH 108/270] Run the tests on PHP 8.1. --- .github/workflows/e2e.yml | 2 +- .github/workflows/test.yml | 2 +- composer.json | 3 +++ tests/acceptance.suite.yml | 1 + tests/integration.suite.yml | 1 + tests/wp-config.php | 6 ++++-- 6 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 0fea596..c4f8c28 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -33,7 +33,7 @@ jobs: build: strategy: matrix: - php: ['8.0','7.4'] + php: ['8.1','8.0','7.4'] wp: ['*', 'dev-nightly'] fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 105a3f6..1ebcc56 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: build: strategy: matrix: - php: ['8.0','7.3'] + php: ['8.1','8.0','7.3'] wp: ['*', 'dev-nightly'] fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" diff --git a/composer.json b/composer.json index bd0436b..c6b9e46 100644 --- a/composer.json +++ b/composer.json @@ -67,7 +67,10 @@ "phpstan analyze" ], "test:integration": [ + "wp --path=tests/wordpress db reset --yes", + "wp --path=tests/wordpress core install --title=\"Example\" --admin_user=\"admin\" --admin_password=\"admin\" --admin_email=\"admin@example.com\" --skip-email --url=http://example.org", "codecept run integration --env singlesite --skip-group ms-required", + "wp --path=tests/wordpress core multisite-install --title=\"Example\" --admin_user=\"admin\" --admin_password=\"admin\" --admin_email=\"admin@example.com\" --skip-email --skip-config --url=http://example.org", "codecept run integration --env multisite --skip-group ms-excluded" ], "test:acceptance": [ diff --git a/tests/acceptance.suite.yml b/tests/acceptance.suite.yml index cae3918..ebb5bc1 100644 --- a/tests/acceptance.suite.yml +++ b/tests/acceptance.suite.yml @@ -15,6 +15,7 @@ modules: user: '%WP_TESTS_DB_USER%' password: '%WP_TESTS_DB_PASS%' url: '%TEST_SITE_WP_URL%' + tablePrefix: wp_ dump: false populate: false cleanup: false diff --git a/tests/integration.suite.yml b/tests/integration.suite.yml index daa33d7..f1622d4 100644 --- a/tests/integration.suite.yml +++ b/tests/integration.suite.yml @@ -13,6 +13,7 @@ modules: dbHost: '%WP_TESTS_DB_HOST%' dbUser: '%WP_TESTS_DB_USER%' dbPassword: '%WP_TESTS_DB_PASS%' + tablePrefix: wp_ skipPluggables: true plugins: ['user-switching/user-switching.php'] activatePlugins: ['user-switching/user-switching.php'] diff --git a/tests/wp-config.php b/tests/wp-config.php index 03fe5c2..494e9b2 100644 --- a/tests/wp-config.php +++ b/tests/wp-config.php @@ -3,6 +3,8 @@ * This is the configuration file that's used for the functional tests and WP-CLI commands. */ +mysqli_report( MYSQLI_REPORT_OFF ); + $_root_dir = dirname( __DIR__ ); $_env_dir = __DIR__; @@ -13,8 +15,8 @@ $dotenv->load(); } -// Test with WordPress debug mode (default). -define( 'WP_DEBUG', true ); +// Disable debug mode as it can cause "headers already sent" if there are deprecations +define( 'WP_DEBUG', false ); // Prevent WP-Cron doing its thing during testing. define( 'DISABLE_WP_CRON', true ); From 70e1db88d2bdd74c2398d857418573e36936e9b9 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 01:34:26 +0100 Subject: [PATCH 109/270] Run the tests on PHP 7.3. --- .github/workflows/e2e.yml | 2 +- .github/workflows/test.yml | 2 +- composer.json | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index c4f8c28..0b6ca05 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -33,7 +33,7 @@ jobs: build: strategy: matrix: - php: ['8.1','8.0','7.4'] + php: ['8.1','8.0','7.4','7.1'] wp: ['*', 'dev-nightly'] fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1ebcc56..86ebf3b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: build: strategy: matrix: - php: ['8.1','8.0','7.3'] + php: ['8.1','8.0','7.4','7.1'] wp: ['*', 'dev-nightly'] fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" diff --git a/composer.json b/composer.json index c6b9e46..667f5fd 100644 --- a/composer.json +++ b/composer.json @@ -41,7 +41,6 @@ "phpstan/phpstan": "^1.0", "phpstan/phpstan-deprecation-rules": "^1.0", "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^9", "roots/wordpress": "*", "szepeviktor/phpstan-wordpress": "^1.0", "vlucas/phpdotenv": "^3", From 13f4dc454a5f32ac6b1a6d4c7f535d3cb7f25f99 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 01:37:02 +0100 Subject: [PATCH 110/270] PHP 7.0. --- .github/workflows/e2e.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 0b6ca05..60b75fe 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -33,7 +33,7 @@ jobs: build: strategy: matrix: - php: ['8.1','8.0','7.4','7.1'] + php: ['8.1','8.0','7.4','7.0'] wp: ['*', 'dev-nightly'] fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 86ebf3b..83e985b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: build: strategy: matrix: - php: ['8.1','8.0','7.4','7.1'] + php: ['8.1','8.0','7.4','7.0'] wp: ['*', 'dev-nightly'] fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" From 10410468316a4b7ed3b1ae896a44c95e486e2b11 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 01:41:54 +0100 Subject: [PATCH 111/270] Remove PHPStan when it's not needed so the tests can run. --- .github/workflows/e2e.yml | 6 ++++++ .github/workflows/test.yml | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 60b75fe..e52f4df 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -74,6 +74,12 @@ jobs: - name: Install dependencies run: | sudo systemctl start mysql.service + composer remove \ + phpstan/phpstan \ + szepeviktor/phpstan-wordpress \ + phpstan/phpstan-deprecation-rules \ + phpstan/phpstan-phpunit \ + --dev composer install --prefer-dist composer require --dev --update-with-dependencies --prefer-dist roots/wordpress="${{ matrix.wp }} || *" mysqladmin -uroot -proot create wordpress_test diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 83e985b..509451c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -72,6 +72,12 @@ jobs: - name: Install dependencies run: | sudo systemctl start mysql.service + composer remove \ + phpstan/phpstan \ + szepeviktor/phpstan-wordpress \ + phpstan/phpstan-deprecation-rules \ + phpstan/phpstan-phpunit \ + --dev composer install --prefer-dist composer require --dev --update-with-dependencies --prefer-dist roots/wordpress="${{ matrix.wp }} || *" mysqladmin -uroot -proot create wordpress_test From 0d5614db7846840ddc81bc062085c9241393ae15 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 01:49:15 +0100 Subject: [PATCH 112/270] Remove some return types in the tests. --- tests/integration/capsTest.php | 2 +- tests/integration/pluginTest.php | 4 ++-- tests/integration/switchingTest.php | 5 ++++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/integration/capsTest.php b/tests/integration/capsTest.php index 7dc0bbc..28c3956 100644 --- a/tests/integration/capsTest.php +++ b/tests/integration/capsTest.php @@ -13,7 +13,7 @@ class Capabilities extends Test { /** * @return array> */ - public function data_roles() : array { + public function data_roles() { $roles = [ 'admin' => [ 'admin', diff --git a/tests/integration/pluginTest.php b/tests/integration/pluginTest.php index ea22dea..14f87e3 100644 --- a/tests/integration/pluginTest.php +++ b/tests/integration/pluginTest.php @@ -22,9 +22,9 @@ public function testStableTagMatchesVersion() : void { } /** - * @return array + * @return ?array */ - private function get_readme() :? array { + private function get_readme() { if ( ! isset( $this->readme_data ) ) { $file = dirname( dirname( __DIR__ ) ) . '/readme.md'; diff --git a/tests/integration/switchingTest.php b/tests/integration/switchingTest.php index d995324..4bf0a30 100644 --- a/tests/integration/switchingTest.php +++ b/tests/integration/switchingTest.php @@ -231,7 +231,10 @@ public function _action_switch_off( int $old_user_id ) : void { $this->test_switching_old_user_id = $old_user_id; } - public function _filter_auth_cookie_expiration( int $length, int $user_id, bool $remember ) : int { + /** + * @return int + */ + public function _filter_auth_cookie_expiration( int $length, int $user_id, bool $remember ) { $this->test_switching_auth_cookie_user_id = $user_id; $this->test_switching_auth_cookie_remember = $remember; return $length; From 44c8bcecb92a377b63ee10b7b7776da61e368ee7 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 01:54:09 +0100 Subject: [PATCH 113/270] Remove all return types in the tests. --- tests/integration/Test.php | 12 ++++++------ tests/integration/authTest.php | 12 ++++++------ tests/integration/capsTest.php | 18 +++++++++--------- tests/integration/pluginTest.php | 2 +- tests/integration/sessionsTest.php | 10 +++++----- tests/integration/switchingTest.php | 12 ++++++------ 6 files changed, 33 insertions(+), 33 deletions(-) diff --git a/tests/integration/Test.php b/tests/integration/Test.php index d18a2d2..5fd909a 100644 --- a/tests/integration/Test.php +++ b/tests/integration/Test.php @@ -72,32 +72,32 @@ public function setUp(): void { add_action( 'clear_olduser_cookie', array( $this, 'action_clear_olduser_cookie' ) ); } - public function action_set_auth_cookie( string $cookie, int $expire, int $expiration, int $user_id, string $scheme, string $token ) : void { + public function action_set_auth_cookie( string $cookie, int $expire, int $expiration, int $user_id, string $scheme, string $token ) { $_COOKIE[ SECURE_AUTH_COOKIE ] = $cookie; $_COOKIE[ AUTH_COOKIE ] = $cookie; $this->sessions[ $user_id ] = $token; } - public function action_set_logged_in_cookie( string $cookie, int $expire, int $expiration, int $user_id, string $scheme, string $token ) : void { + public function action_set_logged_in_cookie( string $cookie, int $expire, int $expiration, int $user_id, string $scheme, string $token ) { $_COOKIE[ LOGGED_IN_COOKIE ] = $cookie; } - public function action_clear_auth_cookie() : void { + public function action_clear_auth_cookie() { unset( $_COOKIE[ LOGGED_IN_COOKIE ] ); unset( $_COOKIE[ SECURE_AUTH_COOKIE ] ); unset( $_COOKIE[ AUTH_COOKIE ] ); } - public function action_set_user_switching_cookie( string $cookie, int $expiration, int $user_id, string $scheme, string $token ) : void { + public function action_set_user_switching_cookie( string $cookie, int $expiration, int $user_id, string $scheme, string $token ) { $_COOKIE[ USER_SWITCHING_COOKIE ] = $cookie; $_COOKIE[ USER_SWITCHING_SECURE_COOKIE ] = $cookie; } - public function action_set_olduser_cookie( string $cookie, int $expiration, int $user_id, string $scheme, string $token ) : void { + public function action_set_olduser_cookie( string $cookie, int $expiration, int $user_id, string $scheme, string $token ) { $_COOKIE[ USER_SWITCHING_OLDUSER_COOKIE ] = $cookie; } - public function action_clear_olduser_cookie() : void { + public function action_clear_olduser_cookie() { unset( $_COOKIE[ USER_SWITCHING_COOKIE ] ); unset( $_COOKIE[ USER_SWITCHING_SECURE_COOKIE ] ); unset( $_COOKIE[ USER_SWITCHING_OLDUSER_COOKIE ] ); diff --git a/tests/integration/authTest.php b/tests/integration/authTest.php index e9ba1ff..5a32663 100644 --- a/tests/integration/authTest.php +++ b/tests/integration/authTest.php @@ -11,7 +11,7 @@ */ class Authentication extends Test { - public function testValidCookiePassesAuthentication() : void { + public function testValidCookiePassesAuthentication() { $expiry = time() + 172800; $auth_cookie = wp_generate_auth_cookie( self::$testers['editor']->ID, $expiry, 'auth' ); @@ -20,14 +20,14 @@ public function testValidCookiePassesAuthentication() : void { self::assertFalse( user_switching::authenticate_old_user( self::$testers['admin'] ) ); } - public function testExpiredCookieDoesNotPassAuthentication() : void { + public function testExpiredCookieDoesNotPassAuthentication() { $auth_cookie = wp_generate_auth_cookie( self::$testers['editor']->ID, time() - 1000, 'auth' ); $_COOKIE[ USER_SWITCHING_COOKIE ] = json_encode( array( $auth_cookie ) ); self::assertFalse( user_switching::authenticate_old_user( self::$testers['editor'] ) ); self::assertFalse( user_switching::authenticate_old_user( self::$testers['admin'] ) ); } - public function testValidCookieWithIncorrectSchemeDoesNotPassAuthentication() : void { + public function testValidCookieWithIncorrectSchemeDoesNotPassAuthentication() { $expiry = time() + 172800; $logged_in_cookie = wp_generate_auth_cookie( self::$testers['editor']->ID, $expiry, 'logged_in' ); @@ -40,7 +40,7 @@ public function testValidCookieWithIncorrectSchemeDoesNotPassAuthentication() : self::assertFalse( user_switching::authenticate_old_user( self::$testers['admin'] ) ); } - public function testMalformedCookieDoesNotPassAuthentication() : void { + public function testMalformedCookieDoesNotPassAuthentication() { $_COOKIE[ USER_SWITCHING_COOKIE ] = 'hello'; self::assertFalse( user_switching::authenticate_old_user( self::$testers['editor'] ) ); self::assertFalse( user_switching::authenticate_old_user( self::$testers['admin'] ) ); @@ -49,7 +49,7 @@ public function testMalformedCookieDoesNotPassAuthentication() : void { /** * @testdox A non-JSON encoded cookie does not pass authentication */ - public function testANonJsonEncodedCookieDoesNotPassAuthentication() : void { + public function testANonJsonEncodedCookieDoesNotPassAuthentication() { $expiry = time() + 172800; $auth_cookie = wp_generate_auth_cookie( self::$testers['editor']->ID, $expiry, 'auth' ); @@ -58,7 +58,7 @@ public function testANonJsonEncodedCookieDoesNotPassAuthentication() : void { self::assertFalse( user_switching::authenticate_old_user( self::$testers['admin'] ) ); } - public function testNoCookieDoesNotPassAuthentication() : void { + public function testNoCookieDoesNotPassAuthentication() { unset( $_COOKIE[ USER_SWITCHING_COOKIE ] ); self::assertFalse( user_switching::authenticate_old_user( self::$testers['editor'] ) ); self::assertFalse( user_switching::authenticate_old_user( self::$testers['admin'] ) ); diff --git a/tests/integration/capsTest.php b/tests/integration/capsTest.php index 28c3956..b6d9ed1 100644 --- a/tests/integration/capsTest.php +++ b/tests/integration/capsTest.php @@ -51,7 +51,7 @@ public function data_roles() { return $roles; } - public function testAllRolesAreTested() : void { + public function testAllRolesAreTested() { $tested_roles = array_column( $this->data_roles(), 0 ); self::assertSame( array_keys( self::$testers ), $tested_roles ); @@ -62,7 +62,7 @@ public function testAllRolesAreTested() : void { * @dataProvider data_roles * @testdox User with role of $role can or cannot switch according to role */ - public function testUserCanOrCannotSwitchAccordingToRole( string $role, bool $can_switch ) : void { + public function testUserCanOrCannotSwitchAccordingToRole( string $role, bool $can_switch ) { foreach ( self::$users as $user_role => $user ) { if ( self::$testers[ $role ]->ID === $user->ID ) { # No user can switch to themselves: @@ -80,7 +80,7 @@ public function testUserCanOrCannotSwitchAccordingToRole( string $role, bool $ca self::assertSame( $can_switch, user_can( self::$testers[ $role ]->ID, 'switch_off' ) ); } - public function testAbilityToSwitchUsersCanBeGrantedToUser() : void { + public function testAbilityToSwitchUsersCanBeGrantedToUser() { # Editors cannot switch to other users: $can_already_switch = user_can( self::$testers['editor']->ID, 'switch_to_user', self::$users['admin']->ID ); @@ -100,7 +100,7 @@ public function testAbilityToSwitchUsersCanBeGrantedToUser() : void { self::assertTrue( $can_switch_off ); } - public function testAbilityToSwitchUsersCanBeGrantedToRole() : void { + public function testAbilityToSwitchUsersCanBeGrantedToRole() { # Editors cannot switch to other users: $can_already_switch = user_can( self::$testers['editor']->ID, 'switch_to_user', self::$users['admin']->ID ); @@ -126,7 +126,7 @@ public function testAbilityToSwitchUsersCanBeGrantedToRole() : void { /** * @group ms-excluded */ - public function testAbilityToSwitchUsersCanBeDeniedFromUser() : void { + public function testAbilityToSwitchUsersCanBeDeniedFromUser() { # Admins can switch to other users: $can_already_switch = user_can( self::$testers['admin']->ID, 'switch_to_user', self::$users['author']->ID ); @@ -149,7 +149,7 @@ public function testAbilityToSwitchUsersCanBeDeniedFromUser() : void { /** * @group ms-excluded */ - public function testAbilityToSwitchUsersCanBeDeniedFromRole() : void { + public function testAbilityToSwitchUsersCanBeDeniedFromRole() { # Admins can switch to other users: $can_already_switch = user_can( self::$testers['admin']->ID, 'switch_to_user', self::$users['author']->ID ); @@ -176,7 +176,7 @@ public function testAbilityToSwitchUsersCanBeDeniedFromRole() : void { * @group multisite * @group ms-required */ - public function testAbilityToSwitchUsersCanBeGrantedToAdministratorRoleOnMultisite() : void { + public function testAbilityToSwitchUsersCanBeGrantedToAdministratorRoleOnMultisite() { # Admins on Multisite cannot switch to other users: $can_already_switch = user_can( self::$testers['admin']->ID, 'switch_to_user', self::$users['author']->ID ); @@ -203,7 +203,7 @@ public function testAbilityToSwitchUsersCanBeGrantedToAdministratorRoleOnMultisi * @group multisite * @group ms-required */ - public function testAbilityToSwitchUsersCanBeGrantedToAdministratorUserOnMultisite() : void { + public function testAbilityToSwitchUsersCanBeGrantedToAdministratorUserOnMultisite() { # Admins on Multisite cannot switch to other users: $can_already_switch = user_can( self::$testers['admin']->ID, 'switch_to_user', self::$users['author']->ID ); @@ -227,7 +227,7 @@ public function testAbilityToSwitchUsersCanBeGrantedToAdministratorUserOnMultisi * @dataProvider data_roles * @testdox User with role of $role cannot switch to no user */ - public function testSwitchingToNoUserIsNotAllowed( string $role ) : void { + public function testSwitchingToNoUserIsNotAllowed( string $role ) { self::assertFalse( user_can( self::$testers[ $role ]->ID, 'switch_to_user', 0 ) ); } diff --git a/tests/integration/pluginTest.php b/tests/integration/pluginTest.php index 14f87e3..71f1228 100644 --- a/tests/integration/pluginTest.php +++ b/tests/integration/pluginTest.php @@ -10,7 +10,7 @@ class Readme extends Test { */ private $readme_data; - public function testStableTagMatchesVersion() : void { + public function testStableTagMatchesVersion() { $readme_data = $this->get_readme(); if ( null === $readme_data ) { self::fail( 'There is no readme file' ); diff --git a/tests/integration/sessionsTest.php b/tests/integration/sessionsTest.php index bcb11cd..d819ee4 100644 --- a/tests/integration/sessionsTest.php +++ b/tests/integration/sessionsTest.php @@ -12,7 +12,7 @@ class Sessions extends Test { /** * @covers \switch_to_user */ - public function testExtraSessionsAreNotCreatedForUsersWhenSwitching() : void { + public function testExtraSessionsAreNotCreatedForUsersWhenSwitching() { if ( is_multisite() ) { $admin = self::$testers['super']; } else { @@ -49,7 +49,7 @@ public function testExtraSessionsAreNotCreatedForUsersWhenSwitching() : void { /** * @covers \switch_off_user */ - public function testExtraSessionsAreNotCreatedForUserWhenSwitchingOff() : void { + public function testExtraSessionsAreNotCreatedForUserWhenSwitchingOff() { if ( is_multisite() ) { $admin = self::$testers['super']; } else { @@ -79,7 +79,7 @@ public function testExtraSessionsAreNotCreatedForUserWhenSwitchingOff() : void { * @covers \switch_to_user * @covers \switch_off_user */ - public function testPreviousSessionForUserIsReusedWhenSwitchingBack() : void { + public function testPreviousSessionForUserIsReusedWhenSwitchingBack() { if ( is_multisite() ) { $admin = self::$testers['super']; } else { @@ -132,7 +132,7 @@ public function testPreviousSessionForUserIsReusedWhenSwitchingBack() : void { /** * @covers \switch_to_user */ - public function testExpiredSessionPreventsUserFromSwitchingBack() : void { + public function testExpiredSessionPreventsUserFromSwitchingBack() { if ( is_multisite() ) { $admin = self::$testers['super']; } else { @@ -188,7 +188,7 @@ public function testExpiredSessionPreventsUserFromSwitchingBack() : void { * @covers \switch_to_user * @covers \switch_off_user */ - public function testSessionTokensAreCorrectlyReusedWhenSwitching() : void { + public function testSessionTokensAreCorrectlyReusedWhenSwitching() { if ( is_multisite() ) { $admin = self::$testers['super']; } else { diff --git a/tests/integration/switchingTest.php b/tests/integration/switchingTest.php index 4bf0a30..319e728 100644 --- a/tests/integration/switchingTest.php +++ b/tests/integration/switchingTest.php @@ -40,7 +40,7 @@ public function setUp(): void { /** * @covers \switch_to_user */ - public function testSwitchUserAndBack() : void { + public function testSwitchUserAndBack() { if ( is_multisite() ) { $admin = self::$testers['super']; } else { @@ -145,7 +145,7 @@ public function testSwitchUserAndBack() : void { * @covers \switch_to_user * @covers \switch_off_user */ - public function testSwitchOffAndBack() : void { + public function testSwitchOffAndBack() { if ( is_multisite() ) { $admin = self::$testers['super']; } else { @@ -200,7 +200,7 @@ public function testSwitchOffAndBack() : void { /** * @covers \switch_to_user */ - public function testSwitchToNonExistentUserFails() : void { + public function testSwitchToNonExistentUserFails() { // Switch user $user = switch_to_user( 0 ); @@ -211,7 +211,7 @@ public function testSwitchToNonExistentUserFails() : void { * @testdox Current URL is detected correctly * @covers \user_switching::current_url */ - public function testCurrentUrl() : void { + public function testCurrentUrl() { $url = add_query_arg( 'foo', 'bar', home_url( 'baz' ) ); $this->go_to( $url ); self::assertSame( user_switching::current_url(), $url ); @@ -221,12 +221,12 @@ public function testCurrentUrl() : void { * @param int $user_id * @param int|false $old_user_id */ - public function _action_switch_user( int $user_id, $old_user_id ) : void { + public function _action_switch_user( int $user_id, $old_user_id ) { $this->test_switching_user_id = $user_id; $this->test_switching_old_user_id = $old_user_id; } - public function _action_switch_off( int $old_user_id ) : void { + public function _action_switch_off( int $old_user_id ) { $this->test_switching_user_id = false; $this->test_switching_old_user_id = $old_user_id; } From eed3c7ee1be158a2a7a35b0ba0387893a2b9911a Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 01:56:23 +0100 Subject: [PATCH 114/270] Correct this URL. --- bin/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/test.sh b/bin/test.sh index 779f8d9..a448810 100755 --- a/bin/test.sh +++ b/bin/test.sh @@ -16,7 +16,7 @@ PHP_SERVER_PROCESS_ID=$! # Run the acceptance tests: TEST_SITE_WP_DIR=$WP_CORE_DIR \ -TEST_SITE_WP_URL=$WP_URL \ +TEST_SITE_WP_URL="http://$WP_URL" \ ./vendor/bin/codecept run acceptance --steps "$1" \ || ( TESTS_EXIT_CODE=$? && kill $PHP_SERVER_PROCESS_ID && exit $TESTS_EXIT_CODE ) From 1ff3622b59cc6c472d18296638403c589a6f39db Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 02:00:20 +0100 Subject: [PATCH 115/270] Switch to Codeception's own setup method so we can avoid the dreaded void return type issue. --- tests/integration/Test.php | 4 +--- tests/integration/switchingTest.php | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/integration/Test.php b/tests/integration/Test.php index 5fd909a..22e7ac6 100644 --- a/tests/integration/Test.php +++ b/tests/integration/Test.php @@ -60,9 +60,7 @@ public static function wpSetUpBeforeClass( \WP_UnitTest_Factory $factory ) { /** * @return void */ - public function setUp(): void { - parent::setUp(); - + public function _before() { add_action( 'set_auth_cookie', array( $this, 'action_set_auth_cookie' ), 10, 6 ); add_action( 'set_logged_in_cookie', array( $this, 'action_set_logged_in_cookie' ), 10, 6 ); add_action( 'clear_auth_cookie', array( $this, 'action_clear_auth_cookie' ) ); diff --git a/tests/integration/switchingTest.php b/tests/integration/switchingTest.php index 319e728..8f5b2d2 100644 --- a/tests/integration/switchingTest.php +++ b/tests/integration/switchingTest.php @@ -28,8 +28,8 @@ class Switching extends Test { */ public $test_switching_auth_cookie_remember; - public function setUp(): void { - parent::setUp(); + public function _before() { + parent::_before(); add_action( 'switch_to_user', array( $this, '_action_switch_user' ), 10, 2 ); add_action( 'switch_back_user', array( $this, '_action_switch_user' ), 10, 2 ); From 037ca3156aa5871441ecce8bfa2e072fb19c85a3 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 02:02:22 +0100 Subject: [PATCH 116/270] Fingers crossed. --- .github/workflows/e2e.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index e52f4df..5497d56 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -33,7 +33,7 @@ jobs: build: strategy: matrix: - php: ['8.1','8.0','7.4','7.0'] + php: ['8.1','8.0','7.4','5.6'] wp: ['*', 'dev-nightly'] fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 509451c..4b6cbb6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: build: strategy: matrix: - php: ['8.1','8.0','7.4','7.0'] + php: ['8.1','8.0','7.4','5.6'] wp: ['*', 'dev-nightly'] fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" From cb9ded43e621fcc1450bb5e5bd4cb61355cb84b3 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 02:05:19 +0100 Subject: [PATCH 117/270] Remove type hints. --- tests/integration/Test.php | 8 ++++---- tests/integration/capsTest.php | 4 ++-- tests/integration/switchingTest.php | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/integration/Test.php b/tests/integration/Test.php index 22e7ac6..54ff5c5 100644 --- a/tests/integration/Test.php +++ b/tests/integration/Test.php @@ -70,13 +70,13 @@ public function _before() { add_action( 'clear_olduser_cookie', array( $this, 'action_clear_olduser_cookie' ) ); } - public function action_set_auth_cookie( string $cookie, int $expire, int $expiration, int $user_id, string $scheme, string $token ) { + public function action_set_auth_cookie( $cookie, $expire, $expiration, $user_id, $scheme, $token ) { $_COOKIE[ SECURE_AUTH_COOKIE ] = $cookie; $_COOKIE[ AUTH_COOKIE ] = $cookie; $this->sessions[ $user_id ] = $token; } - public function action_set_logged_in_cookie( string $cookie, int $expire, int $expiration, int $user_id, string $scheme, string $token ) { + public function action_set_logged_in_cookie( $cookie, $expire, $expiration, $user_id, $scheme, $token ) { $_COOKIE[ LOGGED_IN_COOKIE ] = $cookie; } @@ -86,12 +86,12 @@ public function action_clear_auth_cookie() { unset( $_COOKIE[ AUTH_COOKIE ] ); } - public function action_set_user_switching_cookie( string $cookie, int $expiration, int $user_id, string $scheme, string $token ) { + public function action_set_user_switching_cookie( $cookie, $expiration, $user_id, $scheme, $token ) { $_COOKIE[ USER_SWITCHING_COOKIE ] = $cookie; $_COOKIE[ USER_SWITCHING_SECURE_COOKIE ] = $cookie; } - public function action_set_olduser_cookie( string $cookie, int $expiration, int $user_id, string $scheme, string $token ) { + public function action_set_olduser_cookie( $cookie, $expiration, $user_id, $scheme, $token ) { $_COOKIE[ USER_SWITCHING_OLDUSER_COOKIE ] = $cookie; } diff --git a/tests/integration/capsTest.php b/tests/integration/capsTest.php index b6d9ed1..d6c0c5e 100644 --- a/tests/integration/capsTest.php +++ b/tests/integration/capsTest.php @@ -62,7 +62,7 @@ public function testAllRolesAreTested() { * @dataProvider data_roles * @testdox User with role of $role can or cannot switch according to role */ - public function testUserCanOrCannotSwitchAccordingToRole( string $role, bool $can_switch ) { + public function testUserCanOrCannotSwitchAccordingToRole( $role, $can_switch ) { foreach ( self::$users as $user_role => $user ) { if ( self::$testers[ $role ]->ID === $user->ID ) { # No user can switch to themselves: @@ -227,7 +227,7 @@ public function testAbilityToSwitchUsersCanBeGrantedToAdministratorUserOnMultisi * @dataProvider data_roles * @testdox User with role of $role cannot switch to no user */ - public function testSwitchingToNoUserIsNotAllowed( string $role ) { + public function testSwitchingToNoUserIsNotAllowed( $role ) { self::assertFalse( user_can( self::$testers[ $role ]->ID, 'switch_to_user', 0 ) ); } diff --git a/tests/integration/switchingTest.php b/tests/integration/switchingTest.php index 8f5b2d2..7b1ba72 100644 --- a/tests/integration/switchingTest.php +++ b/tests/integration/switchingTest.php @@ -221,12 +221,12 @@ public function testCurrentUrl() { * @param int $user_id * @param int|false $old_user_id */ - public function _action_switch_user( int $user_id, $old_user_id ) { + public function _action_switch_user( $user_id, $old_user_id ) { $this->test_switching_user_id = $user_id; $this->test_switching_old_user_id = $old_user_id; } - public function _action_switch_off( int $old_user_id ) { + public function _action_switch_off( $old_user_id ) { $this->test_switching_user_id = false; $this->test_switching_old_user_id = $old_user_id; } @@ -234,7 +234,7 @@ public function _action_switch_off( int $old_user_id ) { /** * @return int */ - public function _filter_auth_cookie_expiration( int $length, int $user_id, bool $remember ) { + public function _filter_auth_cookie_expiration( $length, $user_id, $remember ) { $this->test_switching_auth_cookie_user_id = $user_id; $this->test_switching_auth_cookie_remember = $remember; return $length; From c6d1c379cf7e0f9347f62da8c25c0007374acabb Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 02:06:22 +0100 Subject: [PATCH 118/270] Remove more type hints. --- tests/_support/AcceptanceTester.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/_support/AcceptanceTester.php b/tests/_support/AcceptanceTester.php index d8898f6..6691c7b 100644 --- a/tests/_support/AcceptanceTester.php +++ b/tests/_support/AcceptanceTester.php @@ -110,7 +110,7 @@ public function canSeeTheElementInLanguage( $selector, $lang ) { * * @param string $text The message text to search for. */ - public function seeAdminSuccessNotice( string $text ) { + public function seeAdminSuccessNotice( $text ) { return $this->see( $text, '.notice-success' ); } @@ -119,7 +119,7 @@ public function seeAdminSuccessNotice( string $text ) { * * @param string $text The message text to search for. */ - public function seeAdminWarningNotice( string $text ) { + public function seeAdminWarningNotice( $text ) { return $this->see( $text, '.notice-warning' ); } @@ -128,7 +128,7 @@ public function seeAdminWarningNotice( string $text ) { * * @param string $text The message text to search for. */ - public function seeAdminErrorNotice( string $text ) { + public function seeAdminErrorNotice( $text ) { return $this->see( $text, '.notice-error' ); } @@ -137,7 +137,7 @@ public function seeAdminErrorNotice( string $text ) { * * @param string $text The message text to search for. */ - public function seeAdminInfoNotice( string $text ) { + public function seeAdminInfoNotice( $text ) { return $this->see( $text, '.notice-info' ); } } From bc099bfa3c49bbf44195b974af2fee0af0f90031 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 02:17:55 +0100 Subject: [PATCH 119/270] Let's try our luck at testing older versions of WordPress. --- .github/workflows/e2e.yml | 7 +++++++ .github/workflows/test.yml | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 5497d56..5d734fd 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -35,6 +35,13 @@ jobs: matrix: php: ['8.1','8.0','7.4','5.6'] wp: ['*', 'dev-nightly'] + include: + # Oldest version that officially supports PHP 7.4: + - php: 7.4 + wp: 5.3 + # Oldest version that officially supports PHP 5.6: + - php: 5.6 + wp: 4.1 fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4b6cbb6..1f27542 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,6 +33,13 @@ jobs: matrix: php: ['8.1','8.0','7.4','5.6'] wp: ['*', 'dev-nightly'] + include: + # Oldest version that officially supports PHP 7.4: + - php: 7.4 + wp: 5.3 + # Oldest version that officially supports PHP 5.6: + - php: 5.6 + wp: 4.1 fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 From 862d592c77a84dc4fce9a5e0d37ed5dea2089dbe Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 02:22:18 +0100 Subject: [PATCH 120/270] Let's try WP 3.7. --- .github/workflows/e2e.yml | 3 +++ .github/workflows/test.yml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 5d734fd..02aa832 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -42,6 +42,9 @@ jobs: # Oldest version that officially supports PHP 5.6: - php: 5.6 wp: 4.1 + # Oldest version supported by User Switching: + - php: 5.6 + wp: 3.7 fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1f27542..0faaa00 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -40,6 +40,9 @@ jobs: # Oldest version that officially supports PHP 5.6: - php: 5.6 wp: 4.1 + # Oldest version supported by User Switching: + - php: 5.6 + wp: 3.7 fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 From bf2da874dbf68b67211faf7130ff4e87a426ecb0 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 02:24:58 +0100 Subject: [PATCH 121/270] This all works so the list can now be trimmed. --- .github/workflows/e2e.yml | 6 ------ .github/workflows/test.yml | 6 ------ 2 files changed, 12 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 02aa832..e49763f 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -36,12 +36,6 @@ jobs: php: ['8.1','8.0','7.4','5.6'] wp: ['*', 'dev-nightly'] include: - # Oldest version that officially supports PHP 7.4: - - php: 7.4 - wp: 5.3 - # Oldest version that officially supports PHP 5.6: - - php: 5.6 - wp: 4.1 # Oldest version supported by User Switching: - php: 5.6 wp: 3.7 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0faaa00..b65c1a8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,12 +34,6 @@ jobs: php: ['8.1','8.0','7.4','5.6'] wp: ['*', 'dev-nightly'] include: - # Oldest version that officially supports PHP 7.4: - - php: 7.4 - wp: 5.3 - # Oldest version that officially supports PHP 5.6: - - php: 5.6 - wp: 4.1 # Oldest version supported by User Switching: - php: 5.6 wp: 3.7 From ddb8c3b58cb448808db361fb9b6b2b6171322d7a Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 02:32:57 +0100 Subject: [PATCH 122/270] These can all run on PHP 8.0. --- .github/workflows/coding-standards.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 4c3f109..01dea14 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -42,7 +42,7 @@ jobs: cache-name: cache-composer-dependencies with: path: ${{ steps.composer-cache.outputs.dir }} - key: 7.4-composer-${{ hashFiles('composer.json') }} + key: 8.0-composer-${{ hashFiles('composer.json') }} - name: PHPCS and PHPStan cache uses: actions/cache@v2 @@ -53,12 +53,12 @@ jobs: # This uses the hash of user-switching.php in its cache key because Actions doesn't support # always pulling in a cache file and simultaneously always updating it, unlike Travis. # This way we always pull in a cache file and refresh it with each new version of the plugin. - key: 7.4-phpcs-${{ hashFiles('user-switching.php') }} + key: 8.0-phpcs-${{ hashFiles('user-switching.php') }} - name: Install PHP uses: shivammathur/setup-php@2.7.0 with: - php-version: '7.4' + php-version: '8.0' coverage: none env: fail-fast: true From 2d35bc48a94a391adbea364758c147f8098a0f2f Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 02:33:01 +0100 Subject: [PATCH 123/270] Docs. --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 1a8c8b2..1ba6681 100644 --- a/readme.md +++ b/readme.md @@ -87,7 +87,7 @@ User Switching is considered **Ethical Open Source** because it meets all of the ### Does this plugin work with PHP 8? -Yes. +Yes, it's actively tested and working up to PHP 8.1. ### What does "Switch off" mean? From b023ab5235da9b1970228e1ec1c428a863eedba6 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 02:36:35 +0100 Subject: [PATCH 124/270] Update actions. --- .github/workflows/coding-standards.yml | 4 ++-- .github/workflows/deploy-assets.yml | 2 +- .github/workflows/deploy-tag.yml | 2 +- .github/workflows/e2e.yml | 4 ++-- .github/workflows/test.yml | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 01dea14..4f9fbec 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -30,7 +30,7 @@ jobs: timeout-minutes: 10 steps: - name: Checkout repository - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: Get Composer cache directory id: composer-cache @@ -56,7 +56,7 @@ jobs: key: 8.0-phpcs-${{ hashFiles('user-switching.php') }} - name: Install PHP - uses: shivammathur/setup-php@2.7.0 + uses: shivammathur/setup-php@2.16.0 with: php-version: '8.0' coverage: none diff --git a/.github/workflows/deploy-assets.yml b/.github/workflows/deploy-assets.yml index 01adf99..d692aeb 100644 --- a/.github/workflows/deploy-assets.yml +++ b/.github/workflows/deploy-assets.yml @@ -13,7 +13,7 @@ jobs: timeout-minutes: 10 steps: - name: Checkout repository - uses: actions/checkout@v1 + uses: actions/checkout@v2 # @TODO need to cache the npm dependencies - name: Install Dependencies diff --git a/.github/workflows/deploy-tag.yml b/.github/workflows/deploy-tag.yml index c858404..2e30cf1 100644 --- a/.github/workflows/deploy-tag.yml +++ b/.github/workflows/deploy-tag.yml @@ -12,7 +12,7 @@ jobs: timeout-minutes: 10 steps: - name: Checkout repository - uses: actions/checkout@v1 + uses: actions/checkout@v2 # @TODO need to cache the npm dependencies - name: Install Dependencies diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index e49763f..4c9da1c 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -45,7 +45,7 @@ jobs: timeout-minutes: 10 steps: - name: Checkout repository - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: Get Composer cache directory id: composer-cache @@ -60,7 +60,7 @@ jobs: key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} - name: Install PHP - uses: shivammathur/setup-php@2.7.0 + uses: shivammathur/setup-php@2.16.0 with: php-version: ${{ matrix.php }} extensions: mysqli, xmlwriter, xdebug diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b65c1a8..0d32780 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -43,7 +43,7 @@ jobs: timeout-minutes: 10 steps: - name: Checkout repository - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: Get Composer cache directory id: composer-cache @@ -58,7 +58,7 @@ jobs: key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} - name: Install PHP - uses: shivammathur/setup-php@2.7.0 + uses: shivammathur/setup-php@2.16.0 with: php-version: ${{ matrix.php }} extensions: mysqli, xmlwriter From ed651497db1d7cc01fbdd819e1abc0371bdff7e7 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 02:54:13 +0100 Subject: [PATCH 125/270] Correct the WP version installer. 3.7 isn't actually available from Roots so defaulted to latest. --- .github/workflows/e2e.yml | 6 +++--- .github/workflows/test.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 4c9da1c..7804915 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -36,9 +36,9 @@ jobs: php: ['8.1','8.0','7.4','5.6'] wp: ['*', 'dev-nightly'] include: - # Oldest version supported by User Switching: + # Oldest version available from Roots: - php: 5.6 - wp: 3.7 + wp: 4.0 fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 @@ -85,7 +85,7 @@ jobs: phpstan/phpstan-phpunit \ --dev composer install --prefer-dist - composer require --dev --update-with-dependencies --prefer-dist roots/wordpress="${{ matrix.wp }} || *" + composer require --dev --update-with-dependencies --prefer-dist roots/wordpress="${{ matrix.wp }}" mysqladmin -uroot -proot create wordpress_test - name: Run the tests diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0d32780..d02c49d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,9 +34,9 @@ jobs: php: ['8.1','8.0','7.4','5.6'] wp: ['*', 'dev-nightly'] include: - # Oldest version supported by User Switching: + # Oldest version available from Roots: - php: 5.6 - wp: 3.7 + wp: 4.0 fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 @@ -83,7 +83,7 @@ jobs: phpstan/phpstan-phpunit \ --dev composer install --prefer-dist - composer require --dev --update-with-dependencies --prefer-dist roots/wordpress="${{ matrix.wp }} || *" + composer require --dev --update-with-dependencies --prefer-dist roots/wordpress="${{ matrix.wp }}" mysqladmin -uroot -proot create wordpress_test - name: Run the tests From b162d1a561f1ee1573fbd6d488f8ced8c10399f7 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 02:55:31 +0100 Subject: [PATCH 126/270] These are strings. --- .github/workflows/e2e.yml | 4 ++-- .github/workflows/test.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 7804915..d00cc9b 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -37,8 +37,8 @@ jobs: wp: ['*', 'dev-nightly'] include: # Oldest version available from Roots: - - php: 5.6 - wp: 4.0 + - php: '5.6' + wp: '4.0' fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d02c49d..b5a91d0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -35,8 +35,8 @@ jobs: wp: ['*', 'dev-nightly'] include: # Oldest version available from Roots: - - php: 5.6 - wp: 4.0 + - php: '5.6' + wp: '4.0' fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 From 332681c3d9dad89ecb85a60e9e57270e6247f687 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 02:57:51 +0100 Subject: [PATCH 127/270] We need to go to 4.1. --- .github/workflows/e2e.yml | 4 ++-- .github/workflows/test.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index d00cc9b..f9e691a 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -36,9 +36,9 @@ jobs: php: ['8.1','8.0','7.4','5.6'] wp: ['*', 'dev-nightly'] include: - # Oldest version available from Roots: + # Oldest version that supports language packs: - php: '5.6' - wp: '4.0' + wp: '4.1' fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b5a91d0..8742308 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,9 +34,9 @@ jobs: php: ['8.1','8.0','7.4','5.6'] wp: ['*', 'dev-nightly'] include: - # Oldest version available from Roots: + # Oldest version that supports language packs: - php: '5.6' - wp: '4.0' + wp: '4.1' fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 From ffc283faa9af6613fadc8c3c243a20f891edec3e Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 03:03:01 +0100 Subject: [PATCH 128/270] We need to go to 4.7. --- .github/workflows/e2e.yml | 4 ++-- .github/workflows/test.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index f9e691a..ec13d07 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -36,9 +36,9 @@ jobs: php: ['8.1','8.0','7.4','5.6'] wp: ['*', 'dev-nightly'] include: - # Oldest version that supports language packs: + # Oldest version that supports user locales: - php: '5.6' - wp: '4.1' + wp: '4.7' fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8742308..f1dfb90 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,9 +34,9 @@ jobs: php: ['8.1','8.0','7.4','5.6'] wp: ['*', 'dev-nightly'] include: - # Oldest version that supports language packs: + # Oldest version that supports user locales: - php: '5.6' - wp: '4.1' + wp: '4.7' fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 From c10c86016a8a6e788bca74b2c6c57c0509897e6a Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 03:07:06 +0100 Subject: [PATCH 129/270] We need to go to 4.9. --- .github/workflows/e2e.yml | 4 ++-- .github/workflows/test.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index ec13d07..c17c6fb 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -36,9 +36,9 @@ jobs: php: ['8.1','8.0','7.4','5.6'] wp: ['*', 'dev-nightly'] include: - # Oldest version that supports user locales: + # Oldest version that passes the `$token` parameter to session actions: - php: '5.6' - wp: '4.7' + wp: '4.9' fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f1dfb90..74bf845 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,9 +34,9 @@ jobs: php: ['8.1','8.0','7.4','5.6'] wp: ['*', 'dev-nightly'] include: - # Oldest version that supports user locales: + # Oldest version that passes the `$token` parameter to session actions: - php: '5.6' - wp: '4.7' + wp: '4.9' fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 From 991dcbf90751b2f043149a33f39448b9b540e8af Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 03:09:00 +0100 Subject: [PATCH 130/270] Acceptance tests can stay on WP 4.7. --- .github/workflows/e2e.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index c17c6fb..ec13d07 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -36,9 +36,9 @@ jobs: php: ['8.1','8.0','7.4','5.6'] wp: ['*', 'dev-nightly'] include: - # Oldest version that passes the `$token` parameter to session actions: + # Oldest version that supports user locales: - php: '5.6' - wp: '4.9' + wp: '4.7' fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 From f701c4482f7c0fa00b3028635c04be613c03c886 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 03:10:35 +0100 Subject: [PATCH 131/270] Use the latest supported PHP versions. --- .github/workflows/e2e.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index ec13d07..53a8c02 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -37,7 +37,7 @@ jobs: wp: ['*', 'dev-nightly'] include: # Oldest version that supports user locales: - - php: '5.6' + - php: '7.1' wp: '4.7' fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 74bf845..218e94e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -35,7 +35,7 @@ jobs: wp: ['*', 'dev-nightly'] include: # Oldest version that passes the `$token` parameter to session actions: - - php: '5.6' + - php: '7.2' wp: '4.9' fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" From e26a616f4cadd58f9a4023c62a40842e29941759 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 03:12:48 +0100 Subject: [PATCH 132/270] Docs. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ddfe09f..bd3c6d1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,7 +36,7 @@ You can clone this repo and activate it like a normal WordPress plugin. If you w * [Composer](https://getcomposer.org/) * [Node](https://nodejs.org/) -* A local web server running WordPress +* A local installation of MariaDB or MySQL ### Setup From 4c86c1e1bb7e4fb9e2553ccea5c9fd681c2e21e8 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 03:29:24 +0100 Subject: [PATCH 133/270] Change this link. --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 1ba6681..76efb38 100644 --- a/readme.md +++ b/readme.md @@ -256,6 +256,6 @@ In addition, User Switching respects the following filters from WordPress core w ### Do you accept donations? -[I am accepting sponsorships via the GitHub Sponsors program](https://johnblackbourn.com/donations/) and any support you can give will help me maintain this plugin and keep it free for everyone. +[I am accepting sponsorships via the GitHub Sponsors program](https://github.com/sponsors/johnbillion) and any support you can give will help me maintain this plugin and keep it free for everyone. From c2559bb00c13d316d8ad1a6b2653b4e5f8c1cba1 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 6 Jan 2022 03:35:10 +0100 Subject: [PATCH 134/270] Minor formatting. --- user-switching.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/user-switching.php b/user-switching.php index c262085..6c3aa2b 100644 --- a/user-switching.php +++ b/user-switching.php @@ -110,8 +110,14 @@ public function action_personal_options( WP_User $user ) { ?> - - + + + + + + + + Date: Thu, 6 Jan 2022 12:49:07 +0100 Subject: [PATCH 135/270] Remove more config that we no longer need. --- composer.json | 3 --- phpcs.xml.dist | 1 - 2 files changed, 4 deletions(-) diff --git a/composer.json b/composer.json index 667f5fd..d24f468 100644 --- a/composer.json +++ b/composer.json @@ -66,10 +66,7 @@ "phpstan analyze" ], "test:integration": [ - "wp --path=tests/wordpress db reset --yes", - "wp --path=tests/wordpress core install --title=\"Example\" --admin_user=\"admin\" --admin_password=\"admin\" --admin_email=\"admin@example.com\" --skip-email --url=http://example.org", "codecept run integration --env singlesite --skip-group ms-required", - "wp --path=tests/wordpress core multisite-install --title=\"Example\" --admin_user=\"admin\" --admin_password=\"admin\" --admin_email=\"admin@example.com\" --skip-email --skip-config --url=http://example.org", "codecept run integration --env multisite --skip-group ms-excluded" ], "test:acceptance": [ diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 6d41c08..e2a35a2 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -9,7 +9,6 @@ */node_modules/* */tests/* */vendor/* - Gruntfile.js From 0205604f861e70304a7c379b989e3ee862a95960 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 25 Jan 2022 21:54:22 +0100 Subject: [PATCH 136/270] Only install language files when they're needed. --- tests/acceptance/Cest.php | 4 ---- tests/acceptance/SwitchFromEnglishCest.php | 4 ++++ tests/acceptance/SwitchToEnglishCest.php | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/acceptance/Cest.php b/tests/acceptance/Cest.php index 5450c40..a0cb0d9 100644 --- a/tests/acceptance/Cest.php +++ b/tests/acceptance/Cest.php @@ -12,9 +12,5 @@ public function _before( AcceptanceTester $I ) { # Activate the plugin: $I->cli( 'plugin activate user-switching' ); - - # Install language files: - $I->cli( 'language core install it_IT' ); - $I->cli( 'language plugin install user-switching it_IT' ); } } diff --git a/tests/acceptance/SwitchFromEnglishCest.php b/tests/acceptance/SwitchFromEnglishCest.php index 45d8c4c..032c2fc 100644 --- a/tests/acceptance/SwitchFromEnglishCest.php +++ b/tests/acceptance/SwitchFromEnglishCest.php @@ -11,6 +11,10 @@ public function _before( AcceptanceTester $I ) { $I->comment( 'I need to be able to switch to user accounts that use a different language' ); $I->comment( 'And see the output of User Switching in my original language' ); + # Install language files: + $I->cli( 'language core install it_IT' ); + $I->cli( 'language plugin install user-switching it_IT' ); + $I->haveUserInDatabase( 'autore', 'author', [ 'display_name' => 'Autore', 'meta' => [ diff --git a/tests/acceptance/SwitchToEnglishCest.php b/tests/acceptance/SwitchToEnglishCest.php index d374e19..e21e1d3 100644 --- a/tests/acceptance/SwitchToEnglishCest.php +++ b/tests/acceptance/SwitchToEnglishCest.php @@ -11,6 +11,10 @@ public function _before( AcceptanceTester $I ) { $I->comment( 'I need to be able to switch between users' ); $I->comment( 'And see the output of User Switching in my original language' ); + # Install language files: + $I->cli( 'language core install it_IT' ); + $I->cli( 'language plugin install user-switching it_IT' ); + $I->haveUserInDatabase( 'admin_it', 'administrator', [ 'display_name' => 'Admin IT', 'meta' => [ From 901f90ac77e1c57663b35eef67491c7535dd0f3b Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 25 Jan 2022 21:54:33 +0100 Subject: [PATCH 137/270] Terminology. --- tests/wp-config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/wp-config.php b/tests/wp-config.php index 494e9b2..bb98550 100644 --- a/tests/wp-config.php +++ b/tests/wp-config.php @@ -1,6 +1,6 @@ Date: Wed, 16 Feb 2022 14:59:23 +0100 Subject: [PATCH 138/270] Cleaner formatting for the readme. --- readme.md | 165 +++++++++++++++++++++++++++++------------------------- 1 file changed, 90 insertions(+), 75 deletions(-) diff --git a/readme.md b/readme.md index 0e06fa1..45105b2 100644 --- a/readme.md +++ b/readme.md @@ -79,9 +79,10 @@ User Switching is considered **Ethical Open Source** because it meets all of the ## Screenshots -1. The *Switch To* link on the Users screen
![The Switch To link on the Users screen](.wordpress-org/screenshot-1.png) - -2. The *Switch To* link on a user's profile
![The Switch To link on a user's profile](.wordpress-org/screenshot-2.png) +1. The *Switch To* link on the Users screen + ![The Switch To link on the Users screen](.wordpress-org/screenshot-1.png) +2. The *Switch To* link on a user's profile + ![The Switch To link on a user's profile](.wordpress-org/screenshot-2.png) ## Frequently Asked Questions @@ -129,14 +130,16 @@ Yes. The `switch_users` meta capability can be explicitly granted to a user or a Yes. User capabilities in WordPress can be set to `false` to deny them from a user. Denying the `switch_users` capability prevents the user from switching users, even if they have the `edit_users` capability. - add_filter( 'user_has_cap', function( $allcaps, $caps, $args, $user ) { - if ( 'switch_to_user' === $args[0] ) { - if ( my_condition() ) { - $allcaps['switch_users'] = false; - } - } - return $allcaps; - }, 9, 4 ); +~~~php +add_filter( 'user_has_cap', function( $allcaps, $caps, $args, $user ) { + if ( 'switch_to_user' === $args[0] ) { + if ( my_condition() ) { + $allcaps['switch_users'] = false; + } + } + return $allcaps; +}, 9, 4 ); +~~~ Note that this needs to happen before User Switching's own capability filtering, hence the priority of `9`. @@ -144,41 +147,47 @@ Note that this needs to happen before User Switching's own capability filtering, Yes. Use the `user_switching::maybe_switch_url()` method for this. It takes care of authentication and returns a nonce-protected URL for the current user to switch into the provided user account. - if ( method_exists( 'user_switching', 'maybe_switch_url' ) ) { - $url = user_switching::maybe_switch_url( $target_user ); - if ( $url ) { - printf( - 'Switch to %2$s', - esc_url( $url ), - esc_html( $target_user->display_name ) - ); - } - } +~~~php +if ( method_exists( 'user_switching', 'maybe_switch_url' ) ) { + $url = user_switching::maybe_switch_url( $target_user ); + if ( $url ) { + printf( + 'Switch to %2$s', + esc_url( $url ), + esc_html( $target_user->display_name ) + ); + } +} +~~~ This link also works for switching back to the original user, but if you want an explicit link for this you can use the following code: - if ( method_exists( 'user_switching', 'get_old_user' ) ) { - $old_user = user_switching::get_old_user(); - if ( $old_user ) { - printf( - 'Switch back to %2$s', - esc_url( user_switching::switch_back_url( $old_user ) ), - esc_html( $old_user->display_name ) - ); - } - } +~~~php +if ( method_exists( 'user_switching', 'get_old_user' ) ) { + $old_user = user_switching::get_old_user(); + if ( $old_user ) { + printf( + 'Switch back to %2$s', + esc_url( user_switching::switch_back_url( $old_user ) ), + esc_html( $old_user->display_name ) + ); + } +} +~~~ ### Can I determine whether the current user switched into their account? Yes. Use the `current_user_switched()` function for this. - if ( function_exists( 'current_user_switched' ) ) { - $switched_user = current_user_switched(); - if ( $switched_user ) { - // User is logged in and has switched into their account. - // $switched_user is the WP_User object for their originating user. - } - } +~~~php +if ( function_exists( 'current_user_switched' ) ) { + $switched_user = current_user_switched(); + if ( $switched_user ) { + // User is logged in and has switched into their account. + // $switched_user is the WP_User object for their originating user. + } +} +~~~ ### Does this plugin allow a user to frame another user for an action? @@ -205,49 +214,55 @@ Yes, there's a third party add-on plugin for this: [Admin Bar User Switching](ht Yes. When a user switches to another account, the `switch_to_user` hook is called: - /** - * Fires when a user switches to another user account. - * - * @since 0.6.0 - * @since 1.4.0 The `$new_token` and `$old_token` parameters were added. - * - * @param int $user_id The ID of the user being switched to. - * @param int $old_user_id The ID of the user being switched from. - * @param string $new_token The token of the session of the user being switched to. Can be an empty string - * or a token for a session that may or may not still be valid. - * @param string $old_token The token of the session of the user being switched from. - */ - do_action( 'switch_to_user', $user_id, $old_user_id, $new_token, $old_token ); +~~~php +/** + * Fires when a user switches to another user account. + * + * @since 0.6.0 + * @since 1.4.0 The `$new_token` and `$old_token` parameters were added. + * + * @param int $user_id The ID of the user being switched to. + * @param int $old_user_id The ID of the user being switched from. + * @param string $new_token The token of the session of the user being switched to. Can be an empty string + * or a token for a session that may or may not still be valid. + * @param string $old_token The token of the session of the user being switched from. + */ +do_action( 'switch_to_user', $user_id, $old_user_id, $new_token, $old_token ); +~~~ When a user switches back to their originating account, the `switch_back_user` hook is called: - /** - * Fires when a user switches back to their originating account. - * - * @since 0.6.0 - * @since 1.4.0 The `$new_token` and `$old_token` parameters were added. - * - * @param int $user_id The ID of the user being switched back to. - * @param int|false $old_user_id The ID of the user being switched from, or false if the user is switching back - * after having been switched off. - * @param string $new_token The token of the session of the user being switched to. Can be an empty string - * or a token for a session that may or may not still be valid. - * @param string $old_token The token of the session of the user being switched from. - */ - do_action( 'switch_back_user', $user_id, $old_user_id, $new_token, $old_token ); +~~~php +/** + * Fires when a user switches back to their originating account. + * + * @since 0.6.0 + * @since 1.4.0 The `$new_token` and `$old_token` parameters were added. + * + * @param int $user_id The ID of the user being switched back to. + * @param int|false $old_user_id The ID of the user being switched from, or false if the user is switching back + * after having been switched off. + * @param string $new_token The token of the session of the user being switched to. Can be an empty string + * or a token for a session that may or may not still be valid. + * @param string $old_token The token of the session of the user being switched from. + */ +do_action( 'switch_back_user', $user_id, $old_user_id, $new_token, $old_token ); +~~~ When a user switches off, the `switch_off_user` hook is called: - /** - * Fires when a user switches off. - * - * @since 0.6.0 - * @since 1.4.0 The `$old_token` parameter was added. - * - * @param int $old_user_id The ID of the user switching off. - * @param string $old_token The token of the session of the user switching off. - */ - do_action( 'switch_off_user', $old_user_id, $old_token ); +~~~php +/** + * Fires when a user switches off. + * + * @since 0.6.0 + * @since 1.4.0 The `$old_token` parameter was added. + * + * @param int $old_user_id The ID of the user switching off. + * @param string $old_token The token of the session of the user switching off. + */ +do_action( 'switch_off_user', $old_user_id, $old_token ); +~~~ In addition, User Switching respects the following filters from WordPress core when appropriate: From 3e2576d91f0513f3d2fed1971b76b962b8f5e75e Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 30 Apr 2022 22:38:33 +0200 Subject: [PATCH 139/270] The autoloader is only needed for dev. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index d24f468..e97b1b2 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,7 @@ "wp-cli/language-command": "^2", "wp-coding-standards/wpcs": "^2" }, - "autoload": { + "autoload-dev": { "psr-4": { "UserSwitching\\Tests\\": "tests/wpunit" } From 9cfc9f7db08d057ce5db087ee5d5643362e99243 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 26 May 2022 23:00:33 +0200 Subject: [PATCH 140/270] Docs. --- readme.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 45105b2..a52a4b8 100644 --- a/readme.md +++ b/readme.md @@ -55,7 +55,7 @@ I maintain several other plugins for developers. Check them out: ### Privacy Statement -User Switching makes use of browser cookies in order to allow users to switch to another account. Its cookies operate using the same mechanism as the authentication cookies in WordPress core, therefore their values contain the user's `user_login` field in plain text which should be treated as potentially personally identifiable information. The names of the cookies are: +User Switching makes use of browser cookies in order to allow users to switch to another account. Its cookies operate using the same mechanism as the authentication cookies in WordPress core, which means their values contain the user's `user_login` field in plain text which should be treated as potentially personally identifiable information (PII) for privacy and regulatory reasons (GDPR, CCPA, etc). The names of the cookies are: * `wordpress_user_sw_{COOKIEHASH}` * `wordpress_user_sw_secure_{COOKIEHASH}` @@ -126,6 +126,17 @@ A user needs the `edit_users` capability in order to switch user accounts. By de Yes. The `switch_users` meta capability can be explicitly granted to a user or a role to allow them to switch users regardless of whether or not they have the `edit_users` capability. For practical purposes, the user or role will also need the `list_users` capability so they can access the Users menu in the WordPress admin area. +~~~php +add_filter( 'user_has_cap', function( $allcaps, $caps, $args, $user ) { + if ( 'switch_to_user' === $args[0] ) { + if ( my_condition( $user ) ) { + $allcaps['switch_users'] = false; + } + } + return $allcaps; +}, 9, 4 ); +~~~ + ### Can the ability to switch accounts be denied from users? Yes. User capabilities in WordPress can be set to `false` to deny them from a user. Denying the `switch_users` capability prevents the user from switching users, even if they have the `edit_users` capability. @@ -133,7 +144,7 @@ Yes. User capabilities in WordPress can be set to `false` to deny them from a us ~~~php add_filter( 'user_has_cap', function( $allcaps, $caps, $args, $user ) { if ( 'switch_to_user' === $args[0] ) { - if ( my_condition() ) { + if ( my_condition( $user ) ) { $allcaps['switch_users'] = false; } } From 9390781ac8cbde372b5247ecf65603508664fe4d Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 26 May 2022 23:00:48 +0200 Subject: [PATCH 141/270] Bump the tested up to version. --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index a52a4b8..99a099d 100644 --- a/readme.md +++ b/readme.md @@ -2,7 +2,7 @@ Stable tag: 1.5.8 Requires at least: 3.7 -Tested up to: 5.9 +Tested up to: 6.0 Requires PHP: 5.3 License: GPL v2 or later Tags: users, profiles, user switching, fast user switching, multisite, buddypress, bbpress, become, user management, developer From 5b51eade9a82fabf94772e59e96d32bf15ab8616 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 26 May 2022 23:12:00 +0200 Subject: [PATCH 142/270] Don't need to install Composer dependencies twice in a row. --- .github/workflows/e2e.yml | 1 - .github/workflows/test.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 53a8c02..a72168c 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -84,7 +84,6 @@ jobs: phpstan/phpstan-deprecation-rules \ phpstan/phpstan-phpunit \ --dev - composer install --prefer-dist composer require --dev --update-with-dependencies --prefer-dist roots/wordpress="${{ matrix.wp }}" mysqladmin -uroot -proot create wordpress_test diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 218e94e..bf83cc0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -82,7 +82,6 @@ jobs: phpstan/phpstan-deprecation-rules \ phpstan/phpstan-phpunit \ --dev - composer install --prefer-dist composer require --dev --update-with-dependencies --prefer-dist roots/wordpress="${{ matrix.wp }}" mysqladmin -uroot -proot create wordpress_test From 9a5ed6ef2bdcc87b38049371d9e101c13ac58558 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 26 May 2022 23:12:09 +0200 Subject: [PATCH 143/270] Docs. --- tests/integration/Test.php | 4 ++-- user-switching.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/integration/Test.php b/tests/integration/Test.php index 54ff5c5..780caea 100644 --- a/tests/integration/Test.php +++ b/tests/integration/Test.php @@ -7,12 +7,12 @@ abstract class Test extends \Codeception\TestCase\WPTestCase { /** - * @var \WP_User[] + * @var array */ protected static $users = array(); /** - * @var \WP_User[] + * @var array */ protected static $testers = array(); diff --git a/user-switching.php b/user-switching.php index 6c3aa2b..aca90ae 100644 --- a/user-switching.php +++ b/user-switching.php @@ -1186,9 +1186,9 @@ function switch_to_user( $user_id, $remember = false, $set_old_user = true ) { /** * Attaches the original user ID and session token to the new session when a user switches to another user. * - * @param array $session Array of extra data. - * @param int $user_id User ID. - * @return array Array of extra data. + * @param array $session Array of extra data. + * @param int $user_id User ID. + * @return array Array of extra data. */ $session_filter = function( array $session, $user_id ) use ( $old_user_id, $old_token ) { $session['switched_from_id'] = $old_user_id; From bd8ca70a58424a745528115e6e96bd08905abd9d Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 21 Jun 2022 14:44:15 +0100 Subject: [PATCH 144/270] Add a Sponsor button to the plugin row meta. --- user-switching.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/user-switching.php b/user-switching.php index aca90ae..41ff4a8 100644 --- a/user-switching.php +++ b/user-switching.php @@ -63,6 +63,7 @@ public function init_hooks() { add_filter( 'login_message', array( $this, 'filter_login_message' ), 1 ); add_filter( 'removable_query_args', array( $this, 'filter_removable_query_args' ) ); add_action( 'wp_meta', array( $this, 'action_wp_meta' ) ); + add_filter( 'plugin_row_meta', array( $this, 'filter_plugin_row_meta' ), 10, 4 ); add_action( 'wp_footer', array( $this, 'action_wp_footer' ) ); add_action( 'personal_options', array( $this, 'action_personal_options' ) ); add_action( 'admin_bar_menu', array( $this, 'action_admin_bar_menu' ), 11 ); @@ -738,6 +739,27 @@ public function action_bbpress_button() { echo ''; } + /** + * Filters the array of row meta for each plugin in the Plugins list table. + * + * @param array $plugin_meta An array of the plugin row's meta data. + * @param string $plugin_file Path to the plugin file relative to the plugins directory. + * @return array An array of the plugin row's meta data. + */ + public function filter_plugin_row_meta( array $plugin_meta, $plugin_file ) { + if ( 'user-switching/user-switching.php' !== $plugin_file ) { + return $plugin_meta; + } + + $plugin_meta[] = sprintf( + '%2$s', + 'https://github.com/sponsors/johnbillion', + esc_html_x( 'Sponsor', 'verb', 'user-switching' ) + ); + + return $plugin_meta; + } + /** * Filters the list of query arguments which get removed from admin area URLs in WordPress. * From ca669d9e356d1752217e95bb04e55b4a3b473551 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 21 Jun 2022 14:44:40 +0100 Subject: [PATCH 145/270] Prevent direct access to the file. Not sure how this got missed for 13 years. --- user-switching.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/user-switching.php b/user-switching.php index 41ff4a8..aa749b6 100644 --- a/user-switching.php +++ b/user-switching.php @@ -30,6 +30,10 @@ * GNU General Public License for more details. */ +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + /** * Main singleton class for the User Switching plugin. */ From d3fd2cc9ec55e2eff0fd5e2d8130cd3ddefec077 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 21 Jun 2022 14:46:15 +0100 Subject: [PATCH 146/270] Streamine the readme file and make some corrections --- readme.md | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/readme.md b/readme.md index 99a099d..c7161f6 100644 --- a/readme.md +++ b/readme.md @@ -5,7 +5,7 @@ Requires at least: 3.7 Tested up to: 6.0 Requires PHP: 5.3 License: GPL v2 or later -Tags: users, profiles, user switching, fast user switching, multisite, buddypress, bbpress, become, user management, developer +Tags: users, user switching, fast user switching, multisite, woocommerce, buddypress, bbpress Contributors: johnbillion Donate link: https://github.com/sponsors/johnbillion @@ -19,15 +19,14 @@ Instant switching between user accounts in WordPress. ## Description -This plugin allows you to quickly swap between user accounts in WordPress at the click of a button. You'll be instantly logged out and logged in as your desired user. This is handy for test environments where you regularly log out and in between different accounts, or for administrators who need to switch between multiple accounts. +This plugin allows you to quickly swap between user accounts in WordPress at the click of a button. You'll be instantly logged out and logged in as your desired user. This is handy for testing environments, for helping customers on WooCommerce sites, or for any site where administrators need to switch between multiple accounts. ### Features * Switch user: Instantly switch to any user account from the *Users* screen. * Switch back: Instantly switch back to your originating account. * Switch off: Log out of your account but retain the ability to instantly switch back in again. - * Switching between users is secure (see the *Security* section below). - * Compatible with WordPress, WordPress Multisite, WooCommerce, BuddyPress, bbPress, and most two-factor authentication plugins. + * Compatible with Multisite, WooCommerce, BuddyPress, bbPress, and most two-factor authentication plugins. ### Security @@ -65,18 +64,6 @@ User Switching does not send data to any third party, nor does it include any th See also the FAQ for some questions relating to privacy and safety when switching between users. -### Ethical Open Source - -User Switching is considered **Ethical Open Source** because it meets all of the criteria of [The Ethical Source Definition (ESD)](https://ethicalsource.dev/definition/): - -1. It benefits the commons. -2. It is created in the open. -3. Its community is welcoming and just. -4. It puts accessibility first. -5. It prioritizes user safety. -6. It protects user privacy. -7. It encourages fair compensation. - ## Screenshots 1. The *Switch To* link on the Users screen @@ -130,13 +117,15 @@ Yes. The `switch_users` meta capability can be explicitly granted to a user or a add_filter( 'user_has_cap', function( $allcaps, $caps, $args, $user ) { if ( 'switch_to_user' === $args[0] ) { if ( my_condition( $user ) ) { - $allcaps['switch_users'] = false; + $allcaps['switch_users'] = true; } } return $allcaps; }, 9, 4 ); ~~~ +Note that this needs to happen before User Switching's own capability filtering, hence the priority of `9`. + ### Can the ability to switch accounts be denied from users? Yes. User capabilities in WordPress can be set to `false` to deny them from a user. Denying the `switch_users` capability prevents the user from switching users, even if they have the `edit_users` capability. From 422635ad06dab402ecde3fc19beb273991816801 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 21 Jun 2022 20:20:15 +0100 Subject: [PATCH 147/270] Remove some ancient fallback handling. --- user-switching.php | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/user-switching.php b/user-switching.php index aa749b6..3a6dfae 100644 --- a/user-switching.php +++ b/user-switching.php @@ -467,16 +467,10 @@ public function action_admin_bar_menu( WP_Admin_Bar $wp_admin_bar ) { return; } - if ( method_exists( $wp_admin_bar, 'get_node' ) ) { - if ( $wp_admin_bar->get_node( 'user-actions' ) ) { - $parent = 'user-actions'; - } else { - return; - } - } elseif ( get_option( 'show_avatars' ) ) { - $parent = 'my-account-with-avatar'; + if ( $wp_admin_bar->get_node( 'user-actions' ) ) { + $parent = 'user-actions'; } else { - $parent = 'my-account'; + return; } $old_user = self::get_old_user(); From 54df363628df34ea72802272893136c79b3a7114 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 21 Jun 2022 21:35:30 +0100 Subject: [PATCH 148/270] Switch to `wordpress-full` for testing. --- .github/workflows/e2e.yml | 2 +- .github/workflows/test.yml | 2 +- composer.json | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index a72168c..46a7c2a 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -84,7 +84,7 @@ jobs: phpstan/phpstan-deprecation-rules \ phpstan/phpstan-phpunit \ --dev - composer require --dev --update-with-dependencies --prefer-dist roots/wordpress="${{ matrix.wp }}" + composer require --dev --update-with-dependencies --prefer-dist roots/wordpress-full="${{ matrix.wp }}" mysqladmin -uroot -proot create wordpress_test - name: Run the tests diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bf83cc0..38e372d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -82,7 +82,7 @@ jobs: phpstan/phpstan-deprecation-rules \ phpstan/phpstan-phpunit \ --dev - composer require --dev --update-with-dependencies --prefer-dist roots/wordpress="${{ matrix.wp }}" + composer require --dev --update-with-dependencies --prefer-dist roots/wordpress-full="${{ matrix.wp }}" mysqladmin -uroot -proot create wordpress_test - name: Run the tests diff --git a/composer.json b/composer.json index e97b1b2..aa02d6f 100644 --- a/composer.json +++ b/composer.json @@ -41,7 +41,8 @@ "phpstan/phpstan": "^1.0", "phpstan/phpstan-deprecation-rules": "^1.0", "phpstan/phpstan-phpunit": "^1.0", - "roots/wordpress": "*", + "roots/wordpress-core-installer": "^1.0.0", + "roots/wordpress-full": "*", "szepeviktor/phpstan-wordpress": "^1.0", "vlucas/phpdotenv": "^3", "wp-cli/core-command": "^2", From 51fc2365bc25aba08a015fbd7be22c19634dbf76 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 21 Jun 2022 22:39:45 +0100 Subject: [PATCH 149/270] Changes to the branch name for roots/wordpress-full nightly. --- .github/workflows/e2e.yml | 4 ++-- .github/workflows/test.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 46a7c2a..fc896ad 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -34,13 +34,13 @@ jobs: strategy: matrix: php: ['8.1','8.0','7.4','5.6'] - wp: ['*', 'dev-nightly'] + wp: ['*', 'dev-main'] include: # Oldest version that supports user locales: - php: '7.1' wp: '4.7' fail-fast: false - name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" + name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp == 'dev-main' && 'nightly' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 timeout-minutes: 10 steps: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 38e372d..e73b663 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -32,13 +32,13 @@ jobs: strategy: matrix: php: ['8.1','8.0','7.4','5.6'] - wp: ['*', 'dev-nightly'] + wp: ['*', 'dev-main'] include: # Oldest version that passes the `$token` parameter to session actions: - php: '7.2' wp: '4.9' fail-fast: false - name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp }} / PHP ${{ matrix.php }}" + name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp == 'dev-main' && 'nightly' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 timeout-minutes: 10 steps: From 545f402322844203af3e461080c9580d01b0956e Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 21 Jun 2022 22:40:14 +0100 Subject: [PATCH 150/270] Ignore a PHPStan error as we support WP < 4.0. --- phpstan.neon.dist | 2 ++ 1 file changed, 2 insertions(+) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index b48d3d9..97af7cf 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -12,6 +12,8 @@ parameters: ignoreErrors: # Uses func_get_args() - '#^Function apply_filters invoked with [34567] parameters, 2 required\.$#' + # The 'token' element was added in WordPress 4.0 + - '#Offset ''token'' on array{username: string, expiration: string, token: string, hmac: string, scheme: string} in isset\(\) always exists and is not nullable\.#' # Covers the breaks after exits in user_switching::action_init() - message: '#^Unreachable statement#' From a010f27b4dedb2feecdd31080d264debfbbb667c Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 21 Jun 2022 22:43:19 +0100 Subject: [PATCH 151/270] More version fixes. --- .github/workflows/e2e.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index fc896ad..22b848b 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -38,7 +38,7 @@ jobs: include: # Oldest version that supports user locales: - php: '7.1' - wp: '4.7' + wp: '4.7.0' fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp == 'dev-main' && 'nightly' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e73b663..e763f28 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,7 +36,7 @@ jobs: include: # Oldest version that passes the `$token` parameter to session actions: - php: '7.2' - wp: '4.9' + wp: '4.9.0' fail-fast: false name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp == 'dev-main' && 'nightly' || matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 From 0b8869892466f5591b5a87b9ec3e1476b81d7a33 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 21 Jun 2022 22:46:51 +0100 Subject: [PATCH 152/270] Ensure an old user ID is set before calling the `switch_to_user` action. --- user-switching.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user-switching.php b/user-switching.php index 3a6dfae..aa2ff01 100644 --- a/user-switching.php +++ b/user-switching.php @@ -1224,7 +1224,7 @@ function switch_to_user( $user_id, $remember = false, $set_old_user = true ) { remove_filter( 'attach_session_information', $session_filter, 99 ); - if ( $set_old_user ) { + if ( $set_old_user && $old_user_id ) { /** * Fires when a user switches to another user account. * From 35b5588cd364d94b6e0619ca66cb0a61222835dc Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 21 Jun 2022 23:01:11 +0100 Subject: [PATCH 153/270] Simplify these package removals. --- .github/workflows/e2e.yml | 4 +--- .github/workflows/test.yml | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 22b848b..f533915 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -79,10 +79,8 @@ jobs: run: | sudo systemctl start mysql.service composer remove \ - phpstan/phpstan \ + "phpstan/*" \ szepeviktor/phpstan-wordpress \ - phpstan/phpstan-deprecation-rules \ - phpstan/phpstan-phpunit \ --dev composer require --dev --update-with-dependencies --prefer-dist roots/wordpress-full="${{ matrix.wp }}" mysqladmin -uroot -proot create wordpress_test diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e763f28..b21b3b5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -77,10 +77,8 @@ jobs: run: | sudo systemctl start mysql.service composer remove \ - phpstan/phpstan \ + "phpstan/*" \ szepeviktor/phpstan-wordpress \ - phpstan/phpstan-deprecation-rules \ - phpstan/phpstan-phpunit \ --dev composer require --dev --update-with-dependencies --prefer-dist roots/wordpress-full="${{ matrix.wp }}" mysqladmin -uroot -proot create wordpress_test From f72d42b541430047801934266db5052bd39878d0 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 22 Jun 2022 00:47:03 +0100 Subject: [PATCH 154/270] More sorting out. --- .github/workflows/e2e.yml | 11 ++++++----- .github/workflows/test.yml | 9 +++++---- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index f533915..e213f50 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -34,13 +34,13 @@ jobs: strategy: matrix: php: ['8.1','8.0','7.4','5.6'] - wp: ['*', 'dev-main'] + wp: ['latest', 'nightly'] include: # Oldest version that supports user locales: - php: '7.1' - wp: '4.7.0' + wp: '4.7' fail-fast: false - name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp == 'dev-main' && 'nightly' || matrix.wp }} / PHP ${{ matrix.php }}" + name: "WP ${{ matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 timeout-minutes: 10 steps: @@ -82,7 +82,8 @@ jobs: "phpstan/*" \ szepeviktor/phpstan-wordpress \ --dev - composer require --dev --update-with-dependencies --prefer-dist roots/wordpress-full="${{ matrix.wp }}" + composer require --dev --update-with-dependencies --prefer-dist \ + roots/wordpress-full="${{ matrix.wp == 'latest' && '*' || matrix.wp == 'nightly' && 'dev-main' || format('~{0}.0', matrix.wp) }}" mysqladmin -uroot -proot create wordpress_test - name: Run the tests @@ -92,5 +93,5 @@ jobs: if: failure() uses: actions/upload-artifact@v2 with: - name: "acceptance-wp-${{ matrix.wp == '*' && 'latest' || matrix.wp }}-php-${{ matrix.php }}" + name: "acceptance-wp-${{ matrix.wp }}-php-${{ matrix.php }}" path: tests/_output diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b21b3b5..769daff 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -32,13 +32,13 @@ jobs: strategy: matrix: php: ['8.1','8.0','7.4','5.6'] - wp: ['*', 'dev-main'] + wp: ['latest', 'nightly'] include: # Oldest version that passes the `$token` parameter to session actions: - php: '7.2' - wp: '4.9.0' + wp: '4.9' fail-fast: false - name: "WP ${{ matrix.wp == '*' && 'latest' || matrix.wp == 'dev-main' && 'nightly' || matrix.wp }} / PHP ${{ matrix.php }}" + name: "WP ${{ matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-18.04 timeout-minutes: 10 steps: @@ -80,7 +80,8 @@ jobs: "phpstan/*" \ szepeviktor/phpstan-wordpress \ --dev - composer require --dev --update-with-dependencies --prefer-dist roots/wordpress-full="${{ matrix.wp }}" + composer require --dev --update-with-dependencies --prefer-dist \ + roots/wordpress-full="${{ matrix.wp == 'latest' && '*' || matrix.wp == 'nightly' && 'dev-main' || format('~{0}.0', matrix.wp) }}" mysqladmin -uroot -proot create wordpress_test - name: Run the tests From 163164ffae2a8c3d9ed1b2aae4c714ce8c0b5946 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 22 Jun 2022 00:57:35 +0100 Subject: [PATCH 155/270] Wish me luck. --- .github/workflows/e2e.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index e213f50..a34644b 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -83,7 +83,7 @@ jobs: szepeviktor/phpstan-wordpress \ --dev composer require --dev --update-with-dependencies --prefer-dist \ - roots/wordpress-full="${{ matrix.wp == 'latest' && '*' || matrix.wp == 'nightly' && 'dev-main' || format('~{0}.0', matrix.wp) }}" + roots/wordpress-full="${{ (matrix.wp == 'latest' && '*') || (matrix.wp == 'nightly' && 'dev-main') || format('~{0}.0', matrix.wp) }}" mysqladmin -uroot -proot create wordpress_test - name: Run the tests diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 769daff..1a3ccbb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -81,7 +81,7 @@ jobs: szepeviktor/phpstan-wordpress \ --dev composer require --dev --update-with-dependencies --prefer-dist \ - roots/wordpress-full="${{ matrix.wp == 'latest' && '*' || matrix.wp == 'nightly' && 'dev-main' || format('~{0}.0', matrix.wp) }}" + roots/wordpress-full="${{ (matrix.wp == 'latest' && '*') || (matrix.wp == 'nightly' && 'dev-main') || format('~{0}.0', matrix.wp) }}" mysqladmin -uroot -proot create wordpress_test - name: Run the tests From c19ce45cc172634a8fd8975ad1537ed6bb4d38a7 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Fri, 24 Jun 2022 16:17:24 +0100 Subject: [PATCH 156/270] Another try at getting this condition correct. --- .github/workflows/e2e.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index a34644b..d581376 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -83,7 +83,7 @@ jobs: szepeviktor/phpstan-wordpress \ --dev composer require --dev --update-with-dependencies --prefer-dist \ - roots/wordpress-full="${{ (matrix.wp == 'latest' && '*') || (matrix.wp == 'nightly' && 'dev-main') || format('~{0}.0', matrix.wp) }}" + roots/wordpress-full="${{ matrix.wp == 'latest' && '*' || (matrix.wp == 'nightly' && 'dev-main' || format('~{0}.0', matrix.wp)) }}" mysqladmin -uroot -proot create wordpress_test - name: Run the tests diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1a3ccbb..a1585de 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -81,7 +81,7 @@ jobs: szepeviktor/phpstan-wordpress \ --dev composer require --dev --update-with-dependencies --prefer-dist \ - roots/wordpress-full="${{ (matrix.wp == 'latest' && '*') || (matrix.wp == 'nightly' && 'dev-main') || format('~{0}.0', matrix.wp) }}" + roots/wordpress-full="${{ matrix.wp == 'latest' && '*' || (matrix.wp == 'nightly' && 'dev-main' || format('~{0}.0', matrix.wp)) }}" mysqladmin -uroot -proot create wordpress_test - name: Run the tests From 17c51f42ae298da2a049d0e11e5d9e531e374185 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 21 Jun 2022 20:25:48 +0100 Subject: [PATCH 157/270] Add a 'Switch back to {user}' link to the WooCommerce login screen. --- user-switching.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/user-switching.php b/user-switching.php index aa2ff01..1118951 100644 --- a/user-switching.php +++ b/user-switching.php @@ -74,6 +74,7 @@ public function init_hooks() { add_action( 'bp_member_header_actions', array( $this, 'action_bp_button' ), 11 ); add_action( 'bp_directory_members_actions', array( $this, 'action_bp_button' ), 11 ); add_action( 'bbp_template_after_user_details', array( $this, 'action_bbpress_button' ) ); + add_action( 'woocommerce_login_form_start', array( $this, 'action_woocommerce_login_form_start' ), 10, 0 ); add_action( 'switch_to_user', array( $this, 'forget_woocommerce_session' ) ); add_action( 'switch_back_user', array( $this, 'forget_woocommerce_session' ) ); } @@ -879,6 +880,16 @@ public static function secure_auth_cookie() { return ( is_ssl() && ( 'https' === parse_url( wp_login_url(), PHP_URL_SCHEME ) ) ); } + /** + * Adds a 'Switch back to {user}' link to the WooCommerce login screen. + * + * @return void + */ + public function action_woocommerce_login_form_start() { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $this->filter_login_message( '' ); + } + /** * Instructs WooCommerce to forget the session for the current user, without deleting it. * From 3a917d5758ec46f216b22af8e830c23322a8817a Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 21 Jun 2022 20:28:30 +0100 Subject: [PATCH 158/270] Add a 'Switch To' link to the WooCommerce order screen. --- user-switching.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/user-switching.php b/user-switching.php index 1118951..7ed22b2 100644 --- a/user-switching.php +++ b/user-switching.php @@ -75,6 +75,7 @@ public function init_hooks() { add_action( 'bp_directory_members_actions', array( $this, 'action_bp_button' ), 11 ); add_action( 'bbp_template_after_user_details', array( $this, 'action_bbpress_button' ) ); add_action( 'woocommerce_login_form_start', array( $this, 'action_woocommerce_login_form_start' ), 10, 0 ); + add_action( 'woocommerce_admin_order_data_after_order_details', array( $this, 'action_woocommerce_order_details' ), 1 ); add_action( 'switch_to_user', array( $this, 'forget_woocommerce_session' ) ); add_action( 'switch_back_user', array( $this, 'forget_woocommerce_session' ) ); } @@ -890,6 +891,30 @@ public function action_woocommerce_login_form_start() { echo $this->filter_login_message( '' ); } + /** + * Adds a 'Switch To' link to the WooCommerce order screen. + * + * @param WC_Order $order The WooCommerce order object. + * @return void + */ + public function action_woocommerce_order_details( WC_Order $order ) { + $user = $order->get_user(); + + if ( ! $user || ! current_user_can( 'switch_to_user', $user->ID ) ) { + return; + } + + $url = add_query_arg( array( + 'redirect_to' => urlencode( $order->get_view_order_url() ), + ), self::switch_to_url( $user ) ); + + printf( + '

%2$s

', + esc_url( $url ), + esc_html__( 'Switch To', 'user-switching' ) + ); + } + /** * Instructs WooCommerce to forget the session for the current user, without deleting it. * From 07be43e51fc958b71fd09df46ebad99fe8b0c47c Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 21 Jun 2022 20:38:43 +0100 Subject: [PATCH 159/270] Add a 'Switch back to {user}' link to the My Account screen in WooCommerce --- user-switching.php | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/user-switching.php b/user-switching.php index 7ed22b2..a4cd8d3 100644 --- a/user-switching.php +++ b/user-switching.php @@ -76,6 +76,8 @@ public function init_hooks() { add_action( 'bbp_template_after_user_details', array( $this, 'action_bbpress_button' ) ); add_action( 'woocommerce_login_form_start', array( $this, 'action_woocommerce_login_form_start' ), 10, 0 ); add_action( 'woocommerce_admin_order_data_after_order_details', array( $this, 'action_woocommerce_order_details' ), 1 ); + add_filter( 'woocommerce_account_menu_items', array( $this, 'filter_woocommerce_account_menu_items' ), 999 ); + add_filter( 'woocommerce_get_endpoint_url', array( $this, 'filter_woocommerce_get_endpoint_url' ), 10, 2 ); add_action( 'switch_to_user', array( $this, 'forget_woocommerce_session' ) ); add_action( 'switch_back_user', array( $this, 'forget_woocommerce_session' ) ); } @@ -915,6 +917,50 @@ public function action_woocommerce_order_details( WC_Order $order ) { ); } + /** + * Adds a 'Switch back to {user}' link to the My Account screen in WooCommerce. + * + * @param array $items Menu items. + * @return array Menu items. + */ + public function filter_woocommerce_account_menu_items( array $items ) { + $old_user = self::get_old_user(); + + if ( ! $old_user ) { + return $items; + } + + $items['user-switching-switch-back'] = sprintf( + /* Translators: 1: user display name; 2: username; */ + __( 'Switch back to %1$s (%2$s)', 'user-switching' ), + $old_user->display_name, + $old_user->user_login + ); + + return $items; + } + + /** + * Sets the URL of the 'Switch back to {user}' link in the My Account screen in WooCommerce. + * + * @param string $url The URL for the menu item. + * @param string $endpoint The endpoint slug for the menu item. + * @return string The URL for the menu item. + */ + public function filter_woocommerce_get_endpoint_url( $url, $endpoint ) { + if ( 'user-switching-switch-back' !== $endpoint ) { + return $url; + } + + $old_user = self::get_old_user(); + + if ( ! $old_user ) { + return $url; + } + + return self::switch_back_url( $old_user ); + } + /** * Instructs WooCommerce to forget the session for the current user, without deleting it. * From f0f1feae77c048543fbf5e4f639db41b98819b30 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 21 Jun 2022 20:39:46 +0100 Subject: [PATCH 160/270] Add PHPStan stubs. --- tests/phpstan/stubs.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/phpstan/stubs.php b/tests/phpstan/stubs.php index d20bf36..c108f60 100644 --- a/tests/phpstan/stubs.php +++ b/tests/phpstan/stubs.php @@ -82,6 +82,18 @@ class WC_Session { public function forget_session() {} } +class WC_Order { + /** + * @return \WP_User|false + */ + public function get_user() {} + + /** + * @return string + */ + public function get_view_order_url() {} +} + /** * @return \WooCommerce */ From 9861d00114143e8956e77668c8f09ce2aef6acc7 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 21 Jun 2022 20:39:52 +0100 Subject: [PATCH 161/270] Docs. --- readme.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index c7161f6..c44213a 100644 --- a/readme.md +++ b/readme.md @@ -87,6 +87,10 @@ The *Switch Off* link can be found in your profile menu in the WordPress toolbar Yes, and you'll also be able to switch users from the Users screen in Network Admin. +### Does this plugin work with WooCommerce? + +Yes, and you'll also be able to switch users from various WooCommerce administration screens. + ### Does this plugin work with BuddyPress? Yes, and you'll also be able to switch users from member profile screens and the member listing screen. @@ -95,10 +99,6 @@ Yes, and you'll also be able to switch users from member profile screens and the Yes, and you'll also be able to switch users from member profile screens. -### Does this plugin work with WooCommerce? - -Yes. For maximum compatibility you should use WooCommerce version 3.6 or later. - ### Does this plugin work if my site is using a two-factor authentication plugin? Yes, mostly. From 4db4a9267773c6f90b55096372f6628b7461859a Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Fri, 24 Jun 2022 18:16:58 +0100 Subject: [PATCH 162/270] Enough of this nonsense. --- phpcs.xml.dist | 2 + tests/integration/Test.php | 16 ++-- tests/integration/capsTest.php | 12 +-- tests/integration/sessionsTest.php | 32 +++---- tests/integration/switchingTest.php | 6 +- tests/wp-config.php | 2 +- user-switching.php | 126 ++++++++++++++-------------- 7 files changed, 99 insertions(+), 97 deletions(-) diff --git a/phpcs.xml.dist b/phpcs.xml.dist index e2a35a2..1dde3a3 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -23,7 +23,9 @@ + + diff --git a/tests/integration/Test.php b/tests/integration/Test.php index 780caea..9bd861e 100644 --- a/tests/integration/Test.php +++ b/tests/integration/Test.php @@ -26,12 +26,12 @@ abstract class Test extends \Codeception\TestCase\WPTestCase { */ public static function wpSetUpBeforeClass( \WP_UnitTest_Factory $factory ) { $roles = array( - 'admin' => 'administrator', - 'editor' => 'editor', - 'author' => 'author', + 'admin' => 'administrator', + 'editor' => 'editor', + 'author' => 'author', 'contributor' => 'contributor', - 'subscriber' => 'subscriber', - 'no_role' => '', + 'subscriber' => 'subscriber', + 'no_role' => '', ); foreach ( $roles as $name => $role ) { @@ -72,8 +72,8 @@ public function _before() { public function action_set_auth_cookie( $cookie, $expire, $expiration, $user_id, $scheme, $token ) { $_COOKIE[ SECURE_AUTH_COOKIE ] = $cookie; - $_COOKIE[ AUTH_COOKIE ] = $cookie; - $this->sessions[ $user_id ] = $token; + $_COOKIE[ AUTH_COOKIE ] = $cookie; + $this->sessions[ $user_id ] = $token; } public function action_set_logged_in_cookie( $cookie, $expire, $expiration, $user_id, $scheme, $token ) { @@ -87,7 +87,7 @@ public function action_clear_auth_cookie() { } public function action_set_user_switching_cookie( $cookie, $expiration, $user_id, $scheme, $token ) { - $_COOKIE[ USER_SWITCHING_COOKIE ] = $cookie; + $_COOKIE[ USER_SWITCHING_COOKIE ] = $cookie; $_COOKIE[ USER_SWITCHING_SECURE_COOKIE ] = $cookie; } diff --git a/tests/integration/capsTest.php b/tests/integration/capsTest.php index d6c0c5e..781de39 100644 --- a/tests/integration/capsTest.php +++ b/tests/integration/capsTest.php @@ -89,7 +89,7 @@ public function testAbilityToSwitchUsersCanBeGrantedToUser() { # Ensure the user can switch: $can_switch_user = user_can( self::$testers['editor']->ID, 'switch_to_user', self::$users['admin']->ID ); - $can_switch_off = user_can( self::$testers['editor']->ID, 'switch_off' ); + $can_switch_off = user_can( self::$testers['editor']->ID, 'switch_off' ); # Revert the cap: self::$testers['editor']->remove_cap( 'switch_users' ); @@ -112,7 +112,7 @@ public function testAbilityToSwitchUsersCanBeGrantedToRole() { # Ensure the user can switch: $can_switch_user = user_can( self::$testers['editor']->ID, 'switch_to_user', self::$users['admin']->ID ); - $can_switch_off = user_can( self::$testers['editor']->ID, 'switch_off' ); + $can_switch_off = user_can( self::$testers['editor']->ID, 'switch_off' ); # Revert the cap: $role->remove_cap( 'switch_users' ); @@ -135,7 +135,7 @@ public function testAbilityToSwitchUsersCanBeDeniedFromUser() { # Ensure the user can no longer switch: $can_switch_user = user_can( self::$testers['admin']->ID, 'switch_to_user', self::$users['author']->ID ); - $can_switch_off = user_can( self::$testers['admin']->ID, 'switch_off' ); + $can_switch_off = user_can( self::$testers['admin']->ID, 'switch_off' ); # Revert the cap: self::$testers['admin']->remove_cap( 'switch_users' ); @@ -161,7 +161,7 @@ public function testAbilityToSwitchUsersCanBeDeniedFromRole() { # Ensure the user can no longer switch: $can_switch_user = user_can( self::$testers['admin']->ID, 'switch_to_user', self::$users['author']->ID ); - $can_switch_off = user_can( self::$testers['admin']->ID, 'switch_off' ); + $can_switch_off = user_can( self::$testers['admin']->ID, 'switch_off' ); # Revert the cap: $role->remove_cap( 'switch_users' ); @@ -188,7 +188,7 @@ public function testAbilityToSwitchUsersCanBeGrantedToAdministratorRoleOnMultisi # Ensure the user can switch: $can_switch_user = user_can( self::$testers['admin']->ID, 'switch_to_user', self::$users['author']->ID ); - $can_switch_off = user_can( self::$testers['admin']->ID, 'switch_off' ); + $can_switch_off = user_can( self::$testers['admin']->ID, 'switch_off' ); # Revert the cap: $role->remove_cap( 'switch_users' ); @@ -212,7 +212,7 @@ public function testAbilityToSwitchUsersCanBeGrantedToAdministratorUserOnMultisi # Ensure the user can switch: $can_switch_user = user_can( self::$testers['admin']->ID, 'switch_to_user', self::$users['author']->ID ); - $can_switch_off = user_can( self::$testers['admin']->ID, 'switch_off' ); + $can_switch_off = user_can( self::$testers['admin']->ID, 'switch_off' ); # Revert the cap: self::$testers['admin']->remove_cap( 'switch_users' ); diff --git a/tests/integration/sessionsTest.php b/tests/integration/sessionsTest.php index d819ee4..a55d9e3 100644 --- a/tests/integration/sessionsTest.php +++ b/tests/integration/sessionsTest.php @@ -21,12 +21,12 @@ public function testExtraSessionsAreNotCreatedForUsersWhenSwitching() { // Set up the admin session manager with a session $admin_manager = WP_Session_Tokens::get_instance( $admin->ID ); - $admin_token = $admin_manager->create( time() + DAY_IN_SECONDS ); - $admin_before = $admin_manager->get_all(); + $admin_token = $admin_manager->create( time() + DAY_IN_SECONDS ); + $admin_before = $admin_manager->get_all(); // Set up the author session manager, but with no session $author_manager = WP_Session_Tokens::get_instance( self::$users['author']->ID ); - $author_before = $author_manager->get_all(); + $author_before = $author_manager->get_all(); // Set up the admin user state wp_set_current_user( $admin->ID ); @@ -58,8 +58,8 @@ public function testExtraSessionsAreNotCreatedForUserWhenSwitchingOff() { // Set up the admin session manager with a session $admin_manager = WP_Session_Tokens::get_instance( $admin->ID ); - $admin_token = $admin_manager->create( time() + DAY_IN_SECONDS ); - $admin_before = $admin_manager->get_all(); + $admin_token = $admin_manager->create( time() + DAY_IN_SECONDS ); + $admin_before = $admin_manager->get_all(); // Set up the admin user state wp_set_current_user( $admin->ID ); @@ -88,8 +88,8 @@ public function testPreviousSessionForUserIsReusedWhenSwitchingBack() { // Set up the admin session manager with a session $admin_manager = WP_Session_Tokens::get_instance( $admin->ID ); - $admin_token = $admin_manager->create( time() + DAY_IN_SECONDS ); - $admin_before = $admin_manager->get_all(); + $admin_token = $admin_manager->create( time() + DAY_IN_SECONDS ); + $admin_before = $admin_manager->get_all(); // Set up the author session manager, but with no session $author_manager = WP_Session_Tokens::get_instance( self::$users['author']->ID ); @@ -141,12 +141,12 @@ public function testExpiredSessionPreventsUserFromSwitchingBack() { // Set up the admin session manager with a session $admin_manager = WP_Session_Tokens::get_instance( $admin->ID ); - $admin_token = $admin_manager->create( time() + DAY_IN_SECONDS ); - $admin_before = $admin_manager->get_all(); + $admin_token = $admin_manager->create( time() + DAY_IN_SECONDS ); + $admin_before = $admin_manager->get_all(); // Set up the author session manager, but with no session $author_manager = WP_Session_Tokens::get_instance( self::$users['author']->ID ); - $author_before = $author_manager->get_all(); + $author_before = $author_manager->get_all(); // Set up the admin user state wp_set_current_user( $admin->ID ); @@ -197,7 +197,7 @@ public function testSessionTokensAreCorrectlyReusedWhenSwitching() { // Set up the admin session manager with a session $admin_manager = WP_Session_Tokens::get_instance( $admin->ID ); - $admin_token = $admin_manager->create( time() + DAY_IN_SECONDS ); + $admin_token = $admin_manager->create( time() + DAY_IN_SECONDS ); // Set up the author session manager, but with no session $author_manager = WP_Session_Tokens::get_instance( self::$users['author']->ID ); @@ -207,10 +207,10 @@ public function testSessionTokensAreCorrectlyReusedWhenSwitching() { wp_set_auth_cookie( $admin->ID, false, '', $admin_token ); // Switch user - $user = switch_to_user( self::$users['author']->ID ); + $user = switch_to_user( self::$users['author']->ID ); $author_token = wp_get_session_token(); - $cookies = user_switching_get_auth_cookie(); - $cookie = end( $cookies ); + $cookies = user_switching_get_auth_cookie(); + $cookie = end( $cookies ); self::assertIsString( $cookie ); @@ -241,9 +241,9 @@ public function testSessionTokensAreCorrectlyReusedWhenSwitching() { self::assertNull( $author_manager->get( $author_token ) ); // Switch off - $off = switch_off_user(); + $off = switch_off_user(); $cookies = user_switching_get_auth_cookie(); - $cookie = end( $cookies ); + $cookie = end( $cookies ); self::assertIsString( $cookie ); diff --git a/tests/integration/switchingTest.php b/tests/integration/switchingTest.php index 7b1ba72..0d38645 100644 --- a/tests/integration/switchingTest.php +++ b/tests/integration/switchingTest.php @@ -222,12 +222,12 @@ public function testCurrentUrl() { * @param int|false $old_user_id */ public function _action_switch_user( $user_id, $old_user_id ) { - $this->test_switching_user_id = $user_id; + $this->test_switching_user_id = $user_id; $this->test_switching_old_user_id = $old_user_id; } public function _action_switch_off( $old_user_id ) { - $this->test_switching_user_id = false; + $this->test_switching_user_id = false; $this->test_switching_old_user_id = $old_user_id; } @@ -235,7 +235,7 @@ public function _action_switch_off( $old_user_id ) { * @return int */ public function _filter_auth_cookie_expiration( $length, $user_id, $remember ) { - $this->test_switching_auth_cookie_user_id = $user_id; + $this->test_switching_auth_cookie_user_id = $user_id; $this->test_switching_auth_cookie_remember = $remember; return $length; } diff --git a/tests/wp-config.php b/tests/wp-config.php index bb98550..b81d141 100644 --- a/tests/wp-config.php +++ b/tests/wp-config.php @@ -6,7 +6,7 @@ mysqli_report( MYSQLI_REPORT_OFF ); $_root_dir = dirname( __DIR__ ); -$_env_dir = __DIR__; +$_env_dir = __DIR__; require_once $_root_dir . '/vendor/autoload.php'; diff --git a/user-switching.php b/user-switching.php index a4cd8d3..dfb3fde 100644 --- a/user-switching.php +++ b/user-switching.php @@ -53,33 +53,33 @@ class user_switching { */ public function init_hooks() { // Required functionality: - add_filter( 'user_has_cap', array( $this, 'filter_user_has_cap' ), 10, 4 ); - add_filter( 'map_meta_cap', array( $this, 'filter_map_meta_cap' ), 10, 4 ); - add_filter( 'user_row_actions', array( $this, 'filter_user_row_actions' ), 10, 2 ); - add_action( 'plugins_loaded', array( $this, 'action_plugins_loaded' ), 1 ); - add_action( 'init', array( $this, 'action_init' ) ); - add_action( 'all_admin_notices', array( $this, 'action_admin_notices' ), 1 ); - add_action( 'wp_logout', 'user_switching_clear_olduser_cookie' ); - add_action( 'wp_login', 'user_switching_clear_olduser_cookie' ); + add_filter( 'user_has_cap', array( $this, 'filter_user_has_cap' ), 10, 4 ); + add_filter( 'map_meta_cap', array( $this, 'filter_map_meta_cap' ), 10, 4 ); + add_filter( 'user_row_actions', array( $this, 'filter_user_row_actions' ), 10, 2 ); + add_action( 'plugins_loaded', array( $this, 'action_plugins_loaded' ), 1 ); + add_action( 'init', array( $this, 'action_init' ) ); + add_action( 'all_admin_notices', array( $this, 'action_admin_notices' ), 1 ); + add_action( 'wp_logout', 'user_switching_clear_olduser_cookie' ); + add_action( 'wp_login', 'user_switching_clear_olduser_cookie' ); // Nice-to-haves: - add_filter( 'ms_user_row_actions', array( $this, 'filter_user_row_actions' ), 10, 2 ); - add_filter( 'login_message', array( $this, 'filter_login_message' ), 1 ); - add_filter( 'removable_query_args', array( $this, 'filter_removable_query_args' ) ); - add_action( 'wp_meta', array( $this, 'action_wp_meta' ) ); - add_filter( 'plugin_row_meta', array( $this, 'filter_plugin_row_meta' ), 10, 4 ); - add_action( 'wp_footer', array( $this, 'action_wp_footer' ) ); - add_action( 'personal_options', array( $this, 'action_personal_options' ) ); - add_action( 'admin_bar_menu', array( $this, 'action_admin_bar_menu' ), 11 ); - add_action( 'bp_member_header_actions', array( $this, 'action_bp_button' ), 11 ); - add_action( 'bp_directory_members_actions', array( $this, 'action_bp_button' ), 11 ); + add_filter( 'ms_user_row_actions', array( $this, 'filter_user_row_actions' ), 10, 2 ); + add_filter( 'login_message', array( $this, 'filter_login_message' ), 1 ); + add_filter( 'removable_query_args', array( $this, 'filter_removable_query_args' ) ); + add_action( 'wp_meta', array( $this, 'action_wp_meta' ) ); + add_filter( 'plugin_row_meta', array( $this, 'filter_plugin_row_meta' ), 10, 4 ); + add_action( 'wp_footer', array( $this, 'action_wp_footer' ) ); + add_action( 'personal_options', array( $this, 'action_personal_options' ) ); + add_action( 'admin_bar_menu', array( $this, 'action_admin_bar_menu' ), 11 ); + add_action( 'bp_member_header_actions', array( $this, 'action_bp_button' ), 11 ); + add_action( 'bp_directory_members_actions', array( $this, 'action_bp_button' ), 11 ); add_action( 'bbp_template_after_user_details', array( $this, 'action_bbpress_button' ) ); - add_action( 'woocommerce_login_form_start', array( $this, 'action_woocommerce_login_form_start' ), 10, 0 ); + add_action( 'woocommerce_login_form_start', array( $this, 'action_woocommerce_login_form_start' ), 10, 0 ); add_action( 'woocommerce_admin_order_data_after_order_details', array( $this, 'action_woocommerce_order_details' ), 1 ); - add_filter( 'woocommerce_account_menu_items', array( $this, 'filter_woocommerce_account_menu_items' ), 999 ); - add_filter( 'woocommerce_get_endpoint_url', array( $this, 'filter_woocommerce_get_endpoint_url' ), 10, 2 ); - add_action( 'switch_to_user', array( $this, 'forget_woocommerce_session' ) ); - add_action( 'switch_back_user', array( $this, 'forget_woocommerce_session' ) ); + add_filter( 'woocommerce_account_menu_items', array( $this, 'filter_woocommerce_account_menu_items' ), 999 ); + add_filter( 'woocommerce_get_endpoint_url', array( $this, 'filter_woocommerce_get_endpoint_url' ), 10, 2 ); + add_action( 'switch_to_user', array( $this, 'forget_woocommerce_session' ) ); + add_action( 'switch_back_user', array( $this, 'forget_woocommerce_session' ) ); } /** @@ -141,7 +141,7 @@ public function action_personal_options( WP_User $user ) { public static function remember() { /** This filter is documented in wp-includes/pluggable.php */ $cookie_life = apply_filters( 'auth_cookie_expiration', 172800, get_current_user_id(), false ); - $current = wp_parse_auth_cookie( '', 'logged_in' ); + $current = wp_parse_auth_cookie( '', 'logged_in' ); if ( ! $current ) { return false; @@ -233,7 +233,7 @@ public function action_init() { } $redirect_to = self::get_redirect( $old_user, $current_user ); - $args = array( + $args = array( 'user_switched' => 'true', 'switched_back' => 'true', ); @@ -263,7 +263,7 @@ public function action_init() { // Switch off: if ( switch_off_user() ) { $redirect_to = self::get_redirect( null, $current_user ); - $args = array( + $args = array( 'switched_off' => 'true', ); @@ -291,10 +291,10 @@ public function action_init() { */ protected static function get_redirect( WP_User $new_user = null, WP_User $old_user = null ) { if ( ! empty( $_REQUEST['redirect_to'] ) ) { - $redirect_to = self::remove_query_args( wp_unslash( $_REQUEST['redirect_to'] ) ); + $redirect_to = self::remove_query_args( wp_unslash( $_REQUEST['redirect_to'] ) ); $requested_redirect_to = wp_unslash( $_REQUEST['redirect_to'] ); } else { - $redirect_to = ''; + $redirect_to = ''; $requested_redirect_to = ''; } @@ -315,17 +315,17 @@ protected static function get_redirect( WP_User $new_user = null, WP_User $old_u * @return void */ public function action_admin_notices() { - $user = wp_get_current_user(); + $user = wp_get_current_user(); $old_user = self::get_old_user(); if ( $old_user ) { $switched_locale = false; - $lang_attr = ''; + $lang_attr = ''; if ( function_exists( 'get_user_locale' ) ) { - $locale = get_user_locale( $old_user ); + $locale = get_user_locale( $old_user ); $switched_locale = switch_to_locale( $locale ); - $lang_attr = str_replace( '_', '-', $locale ); + $lang_attr = str_replace( '_', '-', $locale ); } ?> @@ -342,7 +342,7 @@ public function action_admin_notices() { ?> add_node( array( 'parent' => $parent, - 'id' => 'switch-back', - 'title' => esc_html( sprintf( + 'id' => 'switch-back', + 'title' => esc_html( sprintf( /* Translators: 1: user display name; 2: username; */ __( 'Switch back to %1$s (%2$s)', 'user-switching' ), $old_user->display_name, $old_user->user_login ) ), - 'href' => add_query_arg( array( + 'href' => add_query_arg( array( 'redirect_to' => urlencode( self::current_url() ), ), self::switch_back_url( $old_user ) ), ) ); @@ -505,10 +505,10 @@ public function action_admin_bar_menu( WP_Admin_Bar $wp_admin_bar ) { $wp_admin_bar->add_node( array( 'parent' => $parent, - 'id' => 'switch-off', + 'id' => 'switch-off', /* Translators: "switch off" means to temporarily log out */ - 'title' => esc_html__( 'Switch Off', 'user-switching' ), - 'href' => $url, + 'title' => esc_html__( 'Switch Off', 'user-switching' ), + 'href' => $url, ) ); } @@ -516,23 +516,23 @@ public function action_admin_bar_menu( WP_Admin_Bar $wp_admin_bar ) { if ( $old_user ) { $wp_admin_bar->add_node( array( 'parent' => 'edit', - 'id' => 'author-switch-back', - 'title' => esc_html( sprintf( + 'id' => 'author-switch-back', + 'title' => esc_html( sprintf( /* Translators: 1: user display name; 2: username; */ __( 'Switch back to %1$s (%2$s)', 'user-switching' ), $old_user->display_name, $old_user->user_login ) ), - 'href' => add_query_arg( array( + 'href' => add_query_arg( array( 'redirect_to' => urlencode( self::current_url() ), ), self::switch_back_url( $old_user ) ), ) ); } elseif ( current_user_can( 'switch_to_user', get_queried_object_id() ) ) { $wp_admin_bar->add_node( array( 'parent' => 'edit', - 'id' => 'author-switch-to', - 'title' => esc_html__( 'Switch To', 'user-switching' ), - 'href' => add_query_arg( array( + 'id' => 'author-switch-to', + 'title' => esc_html__( 'Switch To', 'user-switching' ), + 'href' => add_query_arg( array( 'redirect_to' => urlencode( self::current_url() ), ), self::switch_to_url( get_queried_object() ) ), ) ); @@ -702,10 +702,10 @@ public function action_bp_button() { $components = array_keys( buddypress()->active_components ); echo bp_get_button( array( - 'id' => 'user_switching', - 'component' => reset( $components ), - 'link_href' => esc_url( $link ), - 'link_text' => esc_html__( 'Switch To', 'user-switching' ), + 'id' => 'user_switching', + 'component' => reset( $components ), + 'link_href' => esc_url( $link ), + 'link_text' => esc_html__( 'Switch To', 'user-switching' ), 'wrapper_id' => 'user_switching_switch_to', ) ); } @@ -804,9 +804,9 @@ public static function maybe_switch_url( WP_User $user ) { */ public static function switch_to_url( WP_User $user ) { return wp_nonce_url( add_query_arg( array( - 'action' => 'switch_to_user', + 'action' => 'switch_to_user', 'user_id' => $user->ID, - 'nr' => 1, + 'nr' => 1, ), wp_login_url() ), "switch_to_user_{$user->ID}" ); } @@ -819,7 +819,7 @@ public static function switch_to_url( WP_User $user ) { public static function switch_back_url( WP_User $user ) { return wp_nonce_url( add_query_arg( array( 'action' => 'switch_to_olduser', - 'nr' => 1, + 'nr' => 1, ), wp_login_url() ), "switch_to_olduser_{$user->ID}" ); } @@ -832,7 +832,7 @@ public static function switch_back_url( WP_User $user ) { public static function switch_off_url( WP_User $user ) { return wp_nonce_url( add_query_arg( array( 'action' => 'switch_off', - 'nr' => 1, + 'nr' => 1, ), wp_login_url() ), "switch_off_{$user->ID}" ); } @@ -1095,18 +1095,18 @@ private function __construct() {} * @return void */ function user_switching_set_olduser_cookie( $old_user_id, $pop = false, $token = '' ) { - $secure_auth_cookie = user_switching::secure_auth_cookie(); + $secure_auth_cookie = user_switching::secure_auth_cookie(); $secure_olduser_cookie = user_switching::secure_olduser_cookie(); - $expiration = time() + 172800; // 48 hours - $auth_cookie = user_switching_get_auth_cookie(); - $olduser_cookie = wp_generate_auth_cookie( $old_user_id, $expiration, 'logged_in', $token ); + $expiration = time() + 172800; // 48 hours + $auth_cookie = user_switching_get_auth_cookie(); + $olduser_cookie = wp_generate_auth_cookie( $old_user_id, $expiration, 'logged_in', $token ); if ( $secure_auth_cookie ) { $auth_cookie_name = USER_SWITCHING_SECURE_COOKIE; - $scheme = 'secure_auth'; + $scheme = 'secure_auth'; } else { $auth_cookie_name = USER_SWITCHING_COOKIE; - $scheme = 'auth'; + $scheme = 'auth'; } if ( $pop ) { @@ -1269,10 +1269,10 @@ function switch_to_user( $user_id, $remember = false, $set_old_user = true ) { return false; } - $old_user_id = ( is_user_logged_in() ) ? get_current_user_id() : false; - $old_token = function_exists( 'wp_get_session_token' ) ? wp_get_session_token() : ''; + $old_user_id = ( is_user_logged_in() ) ? get_current_user_id() : false; + $old_token = function_exists( 'wp_get_session_token' ) ? wp_get_session_token() : ''; $auth_cookies = user_switching_get_auth_cookie(); - $auth_cookie = end( $auth_cookies ); + $auth_cookie = end( $auth_cookies ); $cookie_parts = $auth_cookie ? wp_parse_auth_cookie( $auth_cookie ) : false; if ( $set_old_user && $old_user_id ) { @@ -1293,7 +1293,7 @@ function switch_to_user( $user_id, $remember = false, $set_old_user = true ) { * @return array Array of extra data. */ $session_filter = function( array $session, $user_id ) use ( $old_user_id, $old_token ) { - $session['switched_from_id'] = $old_user_id; + $session['switched_from_id'] = $old_user_id; $session['switched_from_session'] = $old_token; return $session; }; From 98fcdaa19d31d5884b9c5ffcc71cfd97af39e0ab Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Fri, 24 Jun 2022 18:18:49 +0100 Subject: [PATCH 163/270] Version 1.6.0. --- package.json | 2 +- readme.md | 2 +- user-switching.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 0733c2c..f5bee00 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "user-switching", - "version": "1.5.8", + "version": "1.6.0", "description": "Instant switching between user accounts in WordPress.", "license": "GPL-2.0-or-later", "author": "John Blackbourn", diff --git a/readme.md b/readme.md index c44213a..a3289bc 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ # User Switching -Stable tag: 1.5.8 +Stable tag: 1.6.0 Requires at least: 3.7 Tested up to: 6.0 Requires PHP: 5.3 diff --git a/user-switching.php b/user-switching.php index dfb3fde..8c70266 100644 --- a/user-switching.php +++ b/user-switching.php @@ -10,7 +10,7 @@ * * Plugin Name: User Switching * Description: Instant switching between user accounts in WordPress - * Version: 1.5.8 + * Version: 1.6.0 * Plugin URI: https://wordpress.org/plugins/user-switching/ * Author: John Blackbourn & contributors * Author URI: https://github.com/johnbillion/user-switching/graphs/contributors From 8c83803169a770a9470cc6900024f4e003bc9b00 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Wed, 13 Jul 2022 15:43:58 +0200 Subject: [PATCH 164/270] Exclude `.editorconfig` from dist ZIP Prevents the `.editorconfig` file from being added to the WordPress.org plugin SVN repository. --- .distignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.distignore b/.distignore index 70805e0..d8c81aa 100644 --- a/.distignore +++ b/.distignore @@ -8,6 +8,7 @@ tests vendor # Files +.editorconfig .distignore .gitignore codeception.dist.yml From a79f03ced486fbf31f28c42f12f6672d935ec4ed Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 14 Jul 2022 00:37:43 +0100 Subject: [PATCH 165/270] Split the switch off tests into their own class. --- tests/_support/AcceptanceTester.php | 1 - tests/acceptance/SwitchOffCest.php | 39 +++++++++++++++++++++++++++++ tests/acceptance/SwitchUserCest.php | 9 ------- 3 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 tests/acceptance/SwitchOffCest.php diff --git a/tests/_support/AcceptanceTester.php b/tests/_support/AcceptanceTester.php index 6691c7b..b9f2f93 100644 --- a/tests/_support/AcceptanceTester.php +++ b/tests/_support/AcceptanceTester.php @@ -32,7 +32,6 @@ public function switchToUser( $user_login ) { * Switch off */ public function switchOff() { - $this->amOnAdminPage( '/' ); $this->click( 'Switch Off' ); } diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php new file mode 100644 index 0000000..8814d23 --- /dev/null +++ b/tests/acceptance/SwitchOffCest.php @@ -0,0 +1,39 @@ +comment( 'As an administrator' ); + $I->comment( 'I need to be able to switch off' ); + $I->comment( 'In order to view the site without logging out completely' ); + + $I->haveUserInDatabase( 'editor', 'editor' ); + } + + public function SwitchOffFromDashboardAndBackFromFrontEnd( AcceptanceTester $I ) { + $I->loginAsAdmin(); + $I->amOnAdminPage( '/' ); + $I->switchOff(); + $I->amLoggedOut(); + + $I->switchBack( 'admin' ); + $I->amLoggedInAs( 'admin' ); + $I->dontSeeInCurrentUrl( '/wp-admin' ); + } + + public function SwitchOffFromDashboardAndBackFromLoginScreen( AcceptanceTester $I ) { + $I->loginAsAdmin(); + $I->amOnAdminPage( '/' ); + $I->switchOff(); + $I->amLoggedOut(); + + $I->amOnPage( 'wp-login.php' ); // $I->amOnPage($I->getLoginUrl()); + $I->switchBack( 'admin' ); + $I->seeAdminSuccessNotice( 'Switched back to admin (admin)' ); + $I->amLoggedInAs( 'admin' ); + } +} diff --git a/tests/acceptance/SwitchUserCest.php b/tests/acceptance/SwitchUserCest.php index acd4270..3671612 100644 --- a/tests/acceptance/SwitchUserCest.php +++ b/tests/acceptance/SwitchUserCest.php @@ -25,13 +25,4 @@ public function SwitchToEditorAndBack( AcceptanceTester $I ) { $I->seeAdminSuccessNotice( 'Switched back to admin' ); $I->amLoggedInAs( 'admin' ); } - - public function SwitchOffAndBack( AcceptanceTester $I ) { - $I->loginAsAdmin(); - $I->switchOff(); - $I->amLoggedOut(); - - $I->switchBack( 'admin' ); - $I->amLoggedInAs( 'admin' ); - } } From 1bc2900520dfae5d61cac0488310497976df09ae Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 14 Jul 2022 01:26:18 +0100 Subject: [PATCH 166/270] Add more assertions for redirect URLs. --- tests/acceptance/SwitchOffCest.php | 7 +++++-- tests/acceptance/SwitchUserCest.php | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index 8814d23..7013e35 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -19,10 +19,11 @@ public function SwitchOffFromDashboardAndBackFromFrontEnd( AcceptanceTester $I ) $I->amOnAdminPage( '/' ); $I->switchOff(); $I->amLoggedOut(); + $I->seeCurrentUrlEquals( '?switched_off=true' ); $I->switchBack( 'admin' ); + $I->seeCurrentUrlEquals( '/?user_switched=true&switched_back=true' ); $I->amLoggedInAs( 'admin' ); - $I->dontSeeInCurrentUrl( '/wp-admin' ); } public function SwitchOffFromDashboardAndBackFromLoginScreen( AcceptanceTester $I ) { @@ -30,9 +31,11 @@ public function SwitchOffFromDashboardAndBackFromLoginScreen( AcceptanceTester $ $I->amOnAdminPage( '/' ); $I->switchOff(); $I->amLoggedOut(); + $I->seeCurrentUrlEquals( '?switched_off=true' ); - $I->amOnPage( 'wp-login.php' ); // $I->amOnPage($I->getLoginUrl()); + $I->amOnPage( 'wp-login.php' ); $I->switchBack( 'admin' ); + $I->seeCurrentUrlEquals( '/wp-admin/users.php?user_switched=true&switched_back=true' ); $I->seeAdminSuccessNotice( 'Switched back to admin (admin)' ); $I->amLoggedInAs( 'admin' ); } diff --git a/tests/acceptance/SwitchUserCest.php b/tests/acceptance/SwitchUserCest.php index 3671612..ec88c76 100644 --- a/tests/acceptance/SwitchUserCest.php +++ b/tests/acceptance/SwitchUserCest.php @@ -17,11 +17,13 @@ public function _before( AcceptanceTester $I ) { public function SwitchToEditorAndBack( AcceptanceTester $I ) { $I->loginAsAdmin(); $I->switchToUser( 'editor' ); + $I->seeCurrentUrlEquals( '/wp-admin/?user_switched=true' ); $I->seeAdminSuccessNotice( 'Switched to editor' ); $I->amLoggedInAs( 'editor' ); $I->amOnAdminPage( '/' ); $I->switchBack( 'admin' ); + $I->seeCurrentUrlEquals( '/wp-admin/?user_switched=true&switched_back=true' ); $I->seeAdminSuccessNotice( 'Switched back to admin' ); $I->amLoggedInAs( 'admin' ); } From 11c3967256447a7b9de17b0188a477ed272be186 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 14 Jul 2022 01:40:14 +0100 Subject: [PATCH 167/270] Set a determinate permalink structure during installation. --- composer.json | 1 + tests/acceptance/Cest.php | 1 + 2 files changed, 2 insertions(+) diff --git a/composer.json b/composer.json index aa02d6f..d6e086f 100644 --- a/composer.json +++ b/composer.json @@ -49,6 +49,7 @@ "wp-cli/db-command": "^2", "wp-cli/extension-command": "^2", "wp-cli/language-command": "^2", + "wp-cli/rewrite-command": "^2", "wp-coding-standards/wpcs": "^2" }, "autoload-dev": { diff --git a/tests/acceptance/Cest.php b/tests/acceptance/Cest.php index a0cb0d9..ac62260 100644 --- a/tests/acceptance/Cest.php +++ b/tests/acceptance/Cest.php @@ -9,6 +9,7 @@ public function _before( AcceptanceTester $I ) { # Install WordPress: $I->cli( 'core install --title="Example" --admin_user="admin" --admin_password="admin" --admin_email="admin@example.com" --skip-email' ); + $I->cli( 'rewrite structure "%postname%"' ); # Activate the plugin: $I->cli( 'plugin activate user-switching' ); From 73d04484ec09a559c5197d98c04d45eb93bbbfb5 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 14 Jul 2022 01:41:41 +0100 Subject: [PATCH 168/270] Redirect to the current post, term, user, or comment being edited when switching off. --- tests/acceptance/SwitchOffCest.php | 13 ++++++++ user-switching.php | 48 ++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index 7013e35..133ab6f 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -39,4 +39,17 @@ public function SwitchOffFromDashboardAndBackFromLoginScreen( AcceptanceTester $ $I->seeAdminSuccessNotice( 'Switched back to admin (admin)' ); $I->amLoggedInAs( 'admin' ); } + + public function SwitchOffFromPublishedPostEditingScreen( AcceptanceTester $I ) { + $I->loginAsAdmin(); + $id = $I->havePostInDatabase( [ + 'post_type' => 'post', + 'post_status' => 'publish', + 'post_name' => 'hello-world', + ] ); + $I->amEditingPostWithId( $id ); + $I->switchOff(); + $I->amLoggedOut(); + $I->seeCurrentUrlEquals( '/hello-world?switched_off=true' ); + } } diff --git a/user-switching.php b/user-switching.php index 8c70266..4771635 100644 --- a/user-switching.php +++ b/user-switching.php @@ -497,9 +497,11 @@ public function action_admin_bar_menu( WP_Admin_Bar $wp_admin_bar ) { if ( current_user_can( 'switch_off' ) ) { $url = self::switch_off_url( wp_get_current_user() ); - if ( ! is_admin() ) { + $redirect_to = is_admin() ? self::get_admin_redirect_to() : self::current_url(); + + if ( is_string( $redirect_to ) ) { $url = add_query_arg( array( - 'redirect_to' => urlencode( self::current_url() ), + 'redirect_to' => urlencode( $redirect_to ), ), $url ); } @@ -540,6 +542,48 @@ public function action_admin_bar_menu( WP_Admin_Bar $wp_admin_bar ) { } } + /** + * Returns a context-aware redirect URL for use when switching off in the admin area. + * + * This is used to redirect the user to the URL of the item they're editing at the time. + * + * @return ?string + */ + public static function get_admin_redirect_to() { + if ( ! empty( $_GET['post'] ) ) { + // Post + $post_id = intval( $_GET['post'] ); + + if ( function_exists( 'is_post_publicly_viewable' ) && is_post_publicly_viewable( $post_id ) ) { + $link = get_permalink( $post_id ); + + if ( is_string( $link ) ) { + return $link; + } + } + } elseif ( ! empty( $_GET['tag_ID'] ) ) { + // Term + $term_id = intval( $_GET['tag_ID'] ); + $term = get_term( $term_id ); + + if ( ( $term instanceof WP_Term ) && function_exists( 'is_taxonomy_viewable' ) && is_taxonomy_viewable( $term->taxonomy ) ) { + $link = get_term_link( $term ); + + if ( is_string( $link ) ) { + return $link; + } + } + } elseif ( ! empty( $_GET['user_id'] ) ) { + // User + return get_author_posts_url( intval( $_GET['user_id'] ) ); + } elseif ( ! empty( $_GET['c'] ) ) { + // Comment + return get_comment_link( intval( $_GET['c'] ) ); + } + + return null; + } + /** * Adds a 'Switch back to {user}' link to the Meta sidebar widget. * From 1b0a5ce7d8e1507b9cf092ca10c35332338d0f3f Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 14 Jul 2022 01:56:15 +0100 Subject: [PATCH 169/270] Test adjustments. --- tests/acceptance/SwitchOffCest.php | 2 -- tests/acceptance/SwitchUserCest.php | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index 133ab6f..2baaf1d 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -10,8 +10,6 @@ public function _before( AcceptanceTester $I ) { $I->comment( 'As an administrator' ); $I->comment( 'I need to be able to switch off' ); $I->comment( 'In order to view the site without logging out completely' ); - - $I->haveUserInDatabase( 'editor', 'editor' ); } public function SwitchOffFromDashboardAndBackFromFrontEnd( AcceptanceTester $I ) { diff --git a/tests/acceptance/SwitchUserCest.php b/tests/acceptance/SwitchUserCest.php index ec88c76..5b1f78a 100644 --- a/tests/acceptance/SwitchUserCest.php +++ b/tests/acceptance/SwitchUserCest.php @@ -10,12 +10,12 @@ public function _before( AcceptanceTester $I ) { $I->comment( 'As an administrator' ); $I->comment( 'I need to be able to switch between users' ); $I->comment( 'In order to access different user accounts' ); - - $I->haveUserInDatabase( 'editor', 'editor' ); } public function SwitchToEditorAndBack( AcceptanceTester $I ) { $I->loginAsAdmin(); + $I->haveUserInDatabase( 'editor', 'editor' ); + $I->switchToUser( 'editor' ); $I->seeCurrentUrlEquals( '/wp-admin/?user_switched=true' ); $I->seeAdminSuccessNotice( 'Switched to editor' ); From 3cca079aed6b9135a5bd0977fdbc5635694ed0e3 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 14 Jul 2022 01:56:24 +0100 Subject: [PATCH 170/270] Add a test for draft posts. --- tests/acceptance/SwitchOffCest.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index 2baaf1d..edd9d84 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -50,4 +50,17 @@ public function SwitchOffFromPublishedPostEditingScreen( AcceptanceTester $I ) { $I->amLoggedOut(); $I->seeCurrentUrlEquals( '/hello-world?switched_off=true' ); } + + public function SwitchOffFromDraftPostEditingScreen( AcceptanceTester $I ) { + $I->loginAsAdmin(); + $id = $I->havePostInDatabase( [ + 'post_type' => 'post', + 'post_status' => 'draft', + 'post_name' => 'hello-world', + ] ); + $I->amEditingPostWithId( $id ); + $I->switchOff(); + $I->amLoggedOut(); + $I->seeCurrentUrlEquals( '?switched_off=true' ); + } } From b4fafffa7066bd566ee1c839583ef17f06723546 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 14 Jul 2022 01:58:33 +0100 Subject: [PATCH 171/270] Minimise use of parameters. --- tests/acceptance/SwitchOffCest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index edd9d84..d91f0e0 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -41,7 +41,6 @@ public function SwitchOffFromDashboardAndBackFromLoginScreen( AcceptanceTester $ public function SwitchOffFromPublishedPostEditingScreen( AcceptanceTester $I ) { $I->loginAsAdmin(); $id = $I->havePostInDatabase( [ - 'post_type' => 'post', 'post_status' => 'publish', 'post_name' => 'hello-world', ] ); @@ -54,7 +53,6 @@ public function SwitchOffFromPublishedPostEditingScreen( AcceptanceTester $I ) { public function SwitchOffFromDraftPostEditingScreen( AcceptanceTester $I ) { $I->loginAsAdmin(); $id = $I->havePostInDatabase( [ - 'post_type' => 'post', 'post_status' => 'draft', 'post_name' => 'hello-world', ] ); From 0ad25cee3dfa229389b5fc328a9e4b008fb199e7 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 14 Jul 2022 02:00:13 +0100 Subject: [PATCH 172/270] Standardise the order of assertions. --- tests/acceptance/SwitchOffCest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index d91f0e0..039adf9 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -16,8 +16,8 @@ public function SwitchOffFromDashboardAndBackFromFrontEnd( AcceptanceTester $I ) $I->loginAsAdmin(); $I->amOnAdminPage( '/' ); $I->switchOff(); - $I->amLoggedOut(); $I->seeCurrentUrlEquals( '?switched_off=true' ); + $I->amLoggedOut(); $I->switchBack( 'admin' ); $I->seeCurrentUrlEquals( '/?user_switched=true&switched_back=true' ); @@ -28,8 +28,8 @@ public function SwitchOffFromDashboardAndBackFromLoginScreen( AcceptanceTester $ $I->loginAsAdmin(); $I->amOnAdminPage( '/' ); $I->switchOff(); - $I->amLoggedOut(); $I->seeCurrentUrlEquals( '?switched_off=true' ); + $I->amLoggedOut(); $I->amOnPage( 'wp-login.php' ); $I->switchBack( 'admin' ); @@ -46,8 +46,8 @@ public function SwitchOffFromPublishedPostEditingScreen( AcceptanceTester $I ) { ] ); $I->amEditingPostWithId( $id ); $I->switchOff(); - $I->amLoggedOut(); $I->seeCurrentUrlEquals( '/hello-world?switched_off=true' ); + $I->amLoggedOut(); } public function SwitchOffFromDraftPostEditingScreen( AcceptanceTester $I ) { @@ -58,7 +58,7 @@ public function SwitchOffFromDraftPostEditingScreen( AcceptanceTester $I ) { ] ); $I->amEditingPostWithId( $id ); $I->switchOff(); - $I->amLoggedOut(); $I->seeCurrentUrlEquals( '?switched_off=true' ); + $I->amLoggedOut(); } } From 271ec325cf2a03c280b42371fbd9d2a4e675bb4f Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 14 Jul 2022 21:05:00 +0100 Subject: [PATCH 173/270] Add more redirect assertions. --- tests/acceptance/SwitchUserCest.php | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tests/acceptance/SwitchUserCest.php b/tests/acceptance/SwitchUserCest.php index 5b1f78a..8c5fce9 100644 --- a/tests/acceptance/SwitchUserCest.php +++ b/tests/acceptance/SwitchUserCest.php @@ -12,7 +12,7 @@ public function _before( AcceptanceTester $I ) { $I->comment( 'In order to access different user accounts' ); } - public function SwitchToEditorAndBack( AcceptanceTester $I ) { + public function SwitchToEditorThenBackFromFrontEnd( AcceptanceTester $I ) { $I->loginAsAdmin(); $I->haveUserInDatabase( 'editor', 'editor' ); @@ -21,9 +21,24 @@ public function SwitchToEditorAndBack( AcceptanceTester $I ) { $I->seeAdminSuccessNotice( 'Switched to editor' ); $I->amLoggedInAs( 'editor' ); - $I->amOnAdminPage( '/' ); + $I->amOnPage( '/' ); $I->switchBack( 'admin' ); - $I->seeCurrentUrlEquals( '/wp-admin/?user_switched=true&switched_back=true' ); + $I->seeCurrentUrlEquals( '/?user_switched=true&switched_back=true' ); + $I->amLoggedInAs( 'admin' ); + } + + public function SwitchToEditorThenBackFromAdminArea( AcceptanceTester $I ) { + $I->loginAsAdmin(); + $I->haveUserInDatabase( 'editor', 'editor' ); + + $I->switchToUser( 'editor' ); + $I->seeCurrentUrlEquals( '/wp-admin/?user_switched=true' ); + $I->seeAdminSuccessNotice( 'Switched to editor' ); + $I->amLoggedInAs( 'editor' ); + + $I->amOnAdminPage( 'tools.php' ); + $I->switchBack( 'admin' ); + $I->seeCurrentUrlEquals( '/wp-admin/tools.php?user_switched=true&switched_back=true' ); $I->seeAdminSuccessNotice( 'Switched back to admin' ); $I->amLoggedInAs( 'admin' ); } From 94fbfd3e179ac02c357102297547a18c351a3a3b Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 14 Jul 2022 21:06:38 +0100 Subject: [PATCH 174/270] Move the redirect URL generation logic to the point where the redirect happens. This means when using the block editor and changing the status of a post, the redirect location remains accurate whenever the user chooses to switch off. --- user-switching.php | 116 +++++++++++++++++++++++++++++++++------------ 1 file changed, 85 insertions(+), 31 deletions(-) diff --git a/user-switching.php b/user-switching.php index 4771635..c5ff843 100644 --- a/user-switching.php +++ b/user-switching.php @@ -46,6 +46,13 @@ class user_switching { */ public static $application = 'WordPress/User Switching'; + const REDIRECT_TYPE_NONE = null; + const REDIRECT_TYPE_URL = 'url'; + const REDIRECT_TYPE_POST = 'post'; + const REDIRECT_TYPE_TERM = 'term'; + const REDIRECT_TYPE_USER = 'user'; + const REDIRECT_TYPE_COMMENT = 'comment'; + /** * Sets up all the filters and actions. * @@ -290,12 +297,68 @@ public function action_init() { * @return string The URL to redirect to. */ protected static function get_redirect( WP_User $new_user = null, WP_User $old_user = null ) { + $redirect_to = ''; + $requested_redirect_to = ''; + $redirect_type = self::REDIRECT_TYPE_NONE; + if ( ! empty( $_REQUEST['redirect_to'] ) ) { + // URL $redirect_to = self::remove_query_args( wp_unslash( $_REQUEST['redirect_to'] ) ); $requested_redirect_to = wp_unslash( $_REQUEST['redirect_to'] ); - } else { - $redirect_to = ''; - $requested_redirect_to = ''; + $redirect_type = self::REDIRECT_TYPE_URL; + } elseif ( ! empty( $_GET['redirect_to_post'] ) ) { + // Post + $post_id = absint( $_GET['redirect_to_post'] ); + + if ( function_exists( 'is_post_publicly_viewable' ) && is_post_publicly_viewable( $post_id ) ) { + $link = get_permalink( $post_id ); + + if ( is_string( $link ) ) { + $redirect_to = $link; + $requested_redirect_to = $link; + $redirect_type = self::REDIRECT_TYPE_POST; + } + } + } elseif ( ! empty( $_GET['redirect_to_term'] ) ) { + // Term + $term = get_term( absint( $_GET['redirect_to_term'] ) ); + + if ( ( $term instanceof WP_Term ) && function_exists( 'is_taxonomy_viewable' ) && is_taxonomy_viewable( $term->taxonomy ) ) { + $link = get_term_link( $term ); + + if ( is_string( $link ) ) { + $redirect_to = $link; + $requested_redirect_to = $link; + $redirect_type = self::REDIRECT_TYPE_TERM; + } + } + } elseif ( ! empty( $_GET['redirect_to_user'] ) ) { + // User + $user = get_userdata( absint( $_GET['redirect_to_user'] ) ); + + if ( $user instanceof WP_User ) { + $link = get_author_posts_url( $user->ID ); + + if ( is_string( $link ) ) { + $redirect_to = $link; + $requested_redirect_to = $link; + $redirect_type = self::REDIRECT_TYPE_USER; + } + } + } elseif ( ! empty( $_GET['redirect_to_comment'] ) ) { + // Comment + $comment = get_comment( absint( $_GET['redirect_to_comment'] ) ); + + if ( $comment instanceof WP_Comment ) { + // @todo check comment status and fall back to linking to its post + $link = get_comment_link( $comment ); + + if ( is_string( $link ) ) { + $redirect_to = $link; + $requested_redirect_to = $link; + $redirect_type = self::REDIRECT_TYPE_COMMENT; + } + } } if ( ! $new_user ) { @@ -497,12 +560,12 @@ public function action_admin_bar_menu( WP_Admin_Bar $wp_admin_bar ) { if ( current_user_can( 'switch_off' ) ) { $url = self::switch_off_url( wp_get_current_user() ); - $redirect_to = is_admin() ? self::get_admin_redirect_to() : self::current_url(); + $redirect_to = is_admin() ? self::get_admin_redirect_to() : array( + 'redirect_to' => urlencode( self::current_url() ), + ); - if ( is_string( $redirect_to ) ) { - $url = add_query_arg( array( - 'redirect_to' => urlencode( $redirect_to ), - ), $url ); + if ( is_array( $redirect_to ) ) { + $url = add_query_arg( $redirect_to, $url ); } $wp_admin_bar->add_node( array( @@ -543,42 +606,33 @@ public function action_admin_bar_menu( WP_Admin_Bar $wp_admin_bar ) { } /** - * Returns a context-aware redirect URL for use when switching off in the admin area. + * Returns a context-aware redirect parameter for use when switching off in the admin area. * * This is used to redirect the user to the URL of the item they're editing at the time. * - * @return ?string + * @return ?array */ public static function get_admin_redirect_to() { if ( ! empty( $_GET['post'] ) ) { // Post - $post_id = intval( $_GET['post'] ); - - if ( function_exists( 'is_post_publicly_viewable' ) && is_post_publicly_viewable( $post_id ) ) { - $link = get_permalink( $post_id ); - - if ( is_string( $link ) ) { - return $link; - } - } + return array( + 'redirect_to_post' => intval( $_GET['post'] ), + ); } elseif ( ! empty( $_GET['tag_ID'] ) ) { // Term - $term_id = intval( $_GET['tag_ID'] ); - $term = get_term( $term_id ); - - if ( ( $term instanceof WP_Term ) && function_exists( 'is_taxonomy_viewable' ) && is_taxonomy_viewable( $term->taxonomy ) ) { - $link = get_term_link( $term ); - - if ( is_string( $link ) ) { - return $link; - } - } + return array( + 'redirect_to_term' => intval( $_GET['tag_ID'] ), + ); } elseif ( ! empty( $_GET['user_id'] ) ) { // User - return get_author_posts_url( intval( $_GET['user_id'] ) ); + return array( + 'redirect_to_user' => intval( $_GET['user_id'] ), + ); } elseif ( ! empty( $_GET['c'] ) ) { // Comment - return get_comment_link( intval( $_GET['c'] ) ); + return array( + 'redirect_to_comment' => intval( $_GET['c'] ), + ); } return null; From cb0db28baa3949ca6ff3b74b1a2fcb00277a922f Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 14 Jul 2022 21:06:47 +0100 Subject: [PATCH 175/270] Add a filter for the redirect location. --- user-switching.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/user-switching.php b/user-switching.php index c5ff843..84682a6 100644 --- a/user-switching.php +++ b/user-switching.php @@ -369,7 +369,17 @@ protected static function get_redirect( WP_User $new_user = null, WP_User $old_u $redirect_to = apply_filters( 'login_redirect', $redirect_to, $requested_redirect_to, $new_user ); } - return $redirect_to; + /** + * Filters the redirect location after a user switches to another account or switches off. + * + * @since x.y.z + * + * @param string $redirect_to The target redirect location, or an empty string if none is specified. + * @param string|null $redirect_type The redirect type, see the `user_switching::REDIRECT_*` constants. + * @param WP_User|null $new_user The user being switched to, or null if there is none. + * @param WP_User|null $old_user The user being switched from, or null if there is none. + */ + return apply_filters( 'user_switching_redirect_to', $redirect_to, $redirect_type, $new_user, $old_user ); } /** From e8234be65b2da35f231568f751e9f3f05af73daa Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 14 Jul 2022 22:44:21 +0100 Subject: [PATCH 176/270] Add a test for switching off from the user editing screen. --- tests/acceptance/SwitchOffCest.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index 039adf9..ec89deb 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -61,4 +61,15 @@ public function SwitchOffFromDraftPostEditingScreen( AcceptanceTester $I ) { $I->seeCurrentUrlEquals( '?switched_off=true' ); $I->amLoggedOut(); } + + public function SwitchOffFromUserEditingScreen( AcceptanceTester $I ) { + $I->loginAsAdmin(); + $id = $I->haveUserInDatabase( 'example', 'editor' ); + // https://github.com/lucatume/wp-browser/pull/586 + // $I->amEditingUserWithId( $id ); + $I->amOnAdminPage('/user-edit.php?user_id=' . $id); + $I->switchOff(); + $I->seeCurrentUrlEquals( '/author/example?switched_off=true' ); + $I->amLoggedOut(); + } } From 158f6dcd855a94a09fc3ad15f2bf43d026cc208a Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 30 Jul 2022 00:31:23 +0100 Subject: [PATCH 177/270] Coding standards. --- tests/acceptance/SwitchOffCest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index ec89deb..30bf93e 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -67,7 +67,7 @@ public function SwitchOffFromUserEditingScreen( AcceptanceTester $I ) { $id = $I->haveUserInDatabase( 'example', 'editor' ); // https://github.com/lucatume/wp-browser/pull/586 // $I->amEditingUserWithId( $id ); - $I->amOnAdminPage('/user-edit.php?user_id=' . $id); + $I->amOnAdminPage( '/user-edit.php?user_id=' . $id ); $I->switchOff(); $I->seeCurrentUrlEquals( '/author/example?switched_off=true' ); $I->amLoggedOut(); From d35e1b62e7de866825c16038d88064e85a24a151 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 30 Jul 2022 00:32:07 +0100 Subject: [PATCH 178/270] Allow the redirect location assertion to vary. --- tests/acceptance/SwitchOffCest.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index 30bf93e..ee5c5b8 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -46,7 +46,15 @@ public function SwitchOffFromPublishedPostEditingScreen( AcceptanceTester $I ) { ] ); $I->amEditingPostWithId( $id ); $I->switchOff(); - $I->seeCurrentUrlEquals( '/hello-world?switched_off=true' ); + + try { + // WordPress >= 5.7: + $I->seeCurrentUrlEquals( '/hello-world?switched_off=true' ); + } catch ( \PHPUnit\Framework\ExpectationFailedException $e ) { + // WordPress < 5.7: + $I->seeCurrentUrlEquals( '?switched_off=true' ); + } + $I->amLoggedOut(); } From 2ba6a792b38649f355574d4ee179221c456f8de5 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 30 Jul 2022 00:33:28 +0100 Subject: [PATCH 179/270] Add a test for switching off from the term editing screen. --- tests/acceptance/SwitchOffCest.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index ee5c5b8..9561a4c 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -70,6 +70,23 @@ public function SwitchOffFromDraftPostEditingScreen( AcceptanceTester $I ) { $I->amLoggedOut(); } + public function SwitchOffFromTermEditingScreen( AcceptanceTester $I ) { + $I->loginAsAdmin(); + $term = $I->haveTermInDatabase( 'hello', 'category' ); + $I->amOnAdminPage( '/term.php?taxonomy=category&tag_ID=' . $term[0] ); + $I->switchOff(); + + try { + // WordPress >= 5.1: + $I->seeCurrentUrlEquals( '/category/hello?switched_off=true' ); + } catch ( \PHPUnit\Framework\ExpectationFailedException $e ) { + // WordPress < 5.1: + $I->seeCurrentUrlEquals( '?switched_off=true' ); + } + + $I->amLoggedOut(); + } + public function SwitchOffFromUserEditingScreen( AcceptanceTester $I ) { $I->loginAsAdmin(); $id = $I->haveUserInDatabase( 'example', 'editor' ); From 4072a913e8fe0fa5c5e80c168fab15fdc1b288cc Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 30 Jul 2022 00:42:40 +0100 Subject: [PATCH 180/270] Improve the redirect when switching off while editing a comment. --- tests/acceptance/SwitchOffCest.php | 38 ++++++++++++++++++++++++++++++ user-switching.php | 21 ++++++++++++----- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index 9561a4c..f44e61e 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -97,4 +97,42 @@ public function SwitchOffFromUserEditingScreen( AcceptanceTester $I ) { $I->seeCurrentUrlEquals( '/author/example?switched_off=true' ); $I->amLoggedOut(); } + + public function SwitchOffFromApprovedCommentEditingScreen( AcceptanceTester $I ) { + $I->loginAsAdmin(); + $postId = $I->havePostInDatabase( [ + 'post_status' => 'publish', + 'post_name' => 'leave-a-comment', + ] ); + $commentId = $I->haveCommentInDatabase( $postId, [ + 'comment_approved' => '1', + ] ); + $I->amOnAdminPage( '/comment.php?action=editcomment&c=' . $commentId ); + $I->switchOff(); + $I->seeCurrentUrlEquals( '/leave-a-comment?switched_off=true#comment-' . $commentId ); + $I->amLoggedOut(); + } + + public function SwitchOffFromUnapprovedCommentEditingScreen( AcceptanceTester $I ) { + $I->loginAsAdmin(); + $postId = $I->havePostInDatabase( [ + 'post_status' => 'publish', + 'post_name' => 'leave-a-comment', + ] ); + $commentId = $I->haveCommentInDatabase( $postId, [ + 'comment_approved' => '0', + ] ); + $I->amOnAdminPage( '/comment.php?action=editcomment&c=' . $commentId ); + $I->switchOff(); + + try { + // WordPress >= 5.7: + $I->seeCurrentUrlEquals( '/leave-a-comment?switched_off=true' ); + } catch ( \PHPUnit\Framework\ExpectationFailedException $e ) { + // WordPress < 5.7: + $I->seeCurrentUrlEquals( '?switched_off=true' ); + } + + $I->amLoggedOut(); + } } diff --git a/user-switching.php b/user-switching.php index 84682a6..623a1fa 100644 --- a/user-switching.php +++ b/user-switching.php @@ -350,13 +350,22 @@ protected static function get_redirect( WP_User $new_user = null, WP_User $old_u $comment = get_comment( absint( $_GET['redirect_to_comment'] ) ); if ( $comment instanceof WP_Comment ) { - // @todo check comment status and fall back to linking to its post - $link = get_comment_link( $comment ); + if ( 'approved' === wp_get_comment_status( $comment ) ) { + $link = get_comment_link( $comment ); - if ( is_string( $link ) ) { - $redirect_to = $link; - $requested_redirect_to = $link; - $redirect_type = self::REDIRECT_TYPE_COMMENT; + if ( is_string( $link ) ) { + $redirect_to = $link; + $requested_redirect_to = $link; + $redirect_type = self::REDIRECT_TYPE_COMMENT; + } + } elseif ( function_exists( 'is_post_publicly_viewable' ) && is_post_publicly_viewable( (int) $comment->comment_post_ID ) ) { + $link = get_permalink( (int) $comment->comment_post_ID ); + + if ( is_string( $link ) ) { + $redirect_to = $link; + $requested_redirect_to = $link; + $redirect_type = self::REDIRECT_TYPE_POST; + } } } } From 187fb3cd1ced9d335be4c593e01815504b4e36ef Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 30 Jul 2022 10:37:16 +0100 Subject: [PATCH 181/270] Remove yoda requirements from coding standards. --- phpcs.xml.dist | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 1dde3a3..480f544 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -23,9 +23,7 @@ - - @@ -36,6 +34,10 @@ + + + + From 799577001bc0c6fd3a2973d0688a06392cca567a Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 30 Jul 2022 10:37:29 +0100 Subject: [PATCH 182/270] Improve this method name. --- tests/_support/AcceptanceTester.php | 2 +- tests/acceptance/SwitchFromEnglishCest.php | 2 +- tests/acceptance/SwitchOffCest.php | 4 ++-- tests/acceptance/SwitchToEnglishCest.php | 2 +- tests/acceptance/SwitchUserCest.php | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/_support/AcceptanceTester.php b/tests/_support/AcceptanceTester.php index b9f2f93..e1b503c 100644 --- a/tests/_support/AcceptanceTester.php +++ b/tests/_support/AcceptanceTester.php @@ -40,7 +40,7 @@ public function switchOff() { * * @param string $user_login */ - public function switchBack( $user_login ) { + public function switchBackTo( $user_login ) { $display_name = $this->grabFromDatabase( $this->grabUsersTableName(), 'display_name', diff --git a/tests/acceptance/SwitchFromEnglishCest.php b/tests/acceptance/SwitchFromEnglishCest.php index 032c2fc..0aeb98a 100644 --- a/tests/acceptance/SwitchFromEnglishCest.php +++ b/tests/acceptance/SwitchFromEnglishCest.php @@ -31,7 +31,7 @@ public function SwitchFromEnglishAdminToItalianAuthorAndBack( AcceptanceTester $ $I->canSeeTheElementInLanguage( '#user_switching p', 'en-US' ); $I->amOnAdminPage( '/' ); - $I->switchBack( 'admin' ); + $I->switchBackTo( 'admin' ); $I->canSeeThePageInLanguage( 'en-US' ); $I->seeAdminSuccessNotice( 'Switched back to admin' ); } diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index f44e61e..657dee4 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -19,7 +19,7 @@ public function SwitchOffFromDashboardAndBackFromFrontEnd( AcceptanceTester $I ) $I->seeCurrentUrlEquals( '?switched_off=true' ); $I->amLoggedOut(); - $I->switchBack( 'admin' ); + $I->switchBackTo( 'admin' ); $I->seeCurrentUrlEquals( '/?user_switched=true&switched_back=true' ); $I->amLoggedInAs( 'admin' ); } @@ -32,7 +32,7 @@ public function SwitchOffFromDashboardAndBackFromLoginScreen( AcceptanceTester $ $I->amLoggedOut(); $I->amOnPage( 'wp-login.php' ); - $I->switchBack( 'admin' ); + $I->switchBackTo( 'admin' ); $I->seeCurrentUrlEquals( '/wp-admin/users.php?user_switched=true&switched_back=true' ); $I->seeAdminSuccessNotice( 'Switched back to admin (admin)' ); $I->amLoggedInAs( 'admin' ); diff --git a/tests/acceptance/SwitchToEnglishCest.php b/tests/acceptance/SwitchToEnglishCest.php index e21e1d3..8a56116 100644 --- a/tests/acceptance/SwitchToEnglishCest.php +++ b/tests/acceptance/SwitchToEnglishCest.php @@ -34,7 +34,7 @@ public function SwitchFromItalianAdminToEnglishAuthorAndBack( AcceptanceTester $ $I->canSeeTheElementInLanguage( '#user_switching p', 'it-IT' ); $I->amOnAdminPage( '/' ); - $I->switchBack( 'admin_it' ); + $I->switchBackTo( 'admin_it' ); $I->canSeeThePageInLanguage( 'it-IT' ); $I->seeAdminSuccessNotice( 'Tornato a Admin IT' ); } diff --git a/tests/acceptance/SwitchUserCest.php b/tests/acceptance/SwitchUserCest.php index 8c5fce9..67816a8 100644 --- a/tests/acceptance/SwitchUserCest.php +++ b/tests/acceptance/SwitchUserCest.php @@ -22,7 +22,7 @@ public function SwitchToEditorThenBackFromFrontEnd( AcceptanceTester $I ) { $I->amLoggedInAs( 'editor' ); $I->amOnPage( '/' ); - $I->switchBack( 'admin' ); + $I->switchBackTo( 'admin' ); $I->seeCurrentUrlEquals( '/?user_switched=true&switched_back=true' ); $I->amLoggedInAs( 'admin' ); } @@ -37,7 +37,7 @@ public function SwitchToEditorThenBackFromAdminArea( AcceptanceTester $I ) { $I->amLoggedInAs( 'editor' ); $I->amOnAdminPage( 'tools.php' ); - $I->switchBack( 'admin' ); + $I->switchBackTo( 'admin' ); $I->seeCurrentUrlEquals( '/wp-admin/tools.php?user_switched=true&switched_back=true' ); $I->seeAdminSuccessNotice( 'Switched back to admin' ); $I->amLoggedInAs( 'admin' ); From 895bb3d2b8fbf3fa0b6d5b7a22668be490ca75de Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 30 Jul 2022 10:42:38 +0100 Subject: [PATCH 183/270] Use more appropriate response codes when switching off fails. --- user-switching.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/user-switching.php b/user-switching.php index 623a1fa..5a6764a 100644 --- a/user-switching.php +++ b/user-switching.php @@ -261,7 +261,7 @@ public function action_init() { // Check authentication: if ( ! $current_user || ! current_user_can( 'switch_off' ) ) { /* Translators: "switch off" means to temporarily log out */ - wp_die( esc_html__( 'Could not switch off.', 'user-switching' ) ); + wp_die( esc_html__( 'Could not switch off.', 'user-switching' ), 403 ); } // Check intent: @@ -282,7 +282,7 @@ public function action_init() { exit; } else { /* Translators: "switch off" means to temporarily log out */ - wp_die( esc_html__( 'Could not switch off.', 'user-switching' ) ); + wp_die( esc_html__( 'Could not switch off.', 'user-switching' ), 403 ); } break; From e3843df1b741752437a276f0d9049fbbb541fe9d Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 30 Jul 2022 11:49:03 +0100 Subject: [PATCH 184/270] Use a better placement for the Switch To menu on bbPress profiles. --- user-switching.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user-switching.php b/user-switching.php index 5a6764a..04d832f 100644 --- a/user-switching.php +++ b/user-switching.php @@ -80,7 +80,7 @@ public function init_hooks() { add_action( 'admin_bar_menu', array( $this, 'action_admin_bar_menu' ), 11 ); add_action( 'bp_member_header_actions', array( $this, 'action_bp_button' ), 11 ); add_action( 'bp_directory_members_actions', array( $this, 'action_bp_button' ), 11 ); - add_action( 'bbp_template_after_user_details', array( $this, 'action_bbpress_button' ) ); + add_action( 'bbp_template_after_user_details_menu_items', array( $this, 'action_bbpress_button' ) ); add_action( 'woocommerce_login_form_start', array( $this, 'action_woocommerce_login_form_start' ), 10, 0 ); add_action( 'woocommerce_admin_order_data_after_order_details', array( $this, 'action_woocommerce_order_details' ), 1 ); add_filter( 'woocommerce_account_menu_items', array( $this, 'filter_woocommerce_account_menu_items' ), 999 ); From 477b80e6b33df3de708efcc4c04a4fca5dec5281 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 30 Jul 2022 12:01:39 +0100 Subject: [PATCH 185/270] Clean up user-facing messages by removing the user login in brackets. Not changing the internationalised strings means all the existing translations on wordpress.org don't get invalidated. --- tests/_support/AcceptanceTester.php | 5 +- tests/acceptance/SwitchFromEnglishCest.php | 4 +- tests/acceptance/SwitchOffCest.php | 2 +- tests/acceptance/SwitchToEnglishCest.php | 4 +- tests/acceptance/SwitchUserCest.php | 6 +- user-switching.php | 136 +++++++++++---------- 6 files changed, 83 insertions(+), 74 deletions(-) diff --git a/tests/_support/AcceptanceTester.php b/tests/_support/AcceptanceTester.php index e1b503c..591f383 100644 --- a/tests/_support/AcceptanceTester.php +++ b/tests/_support/AcceptanceTester.php @@ -50,9 +50,8 @@ public function switchBackTo( $user_login ) { ); $this->click( sprintf( - 'Switch back to %1$s (%2$s)', - $display_name, - $user_login + 'Switch back to %s', + $display_name ) ); } diff --git a/tests/acceptance/SwitchFromEnglishCest.php b/tests/acceptance/SwitchFromEnglishCest.php index 0aeb98a..1ef50b8 100644 --- a/tests/acceptance/SwitchFromEnglishCest.php +++ b/tests/acceptance/SwitchFromEnglishCest.php @@ -27,12 +27,12 @@ public function SwitchFromEnglishAdminToItalianAuthorAndBack( AcceptanceTester $ $I->loginAsAdmin(); $I->switchToUser( 'autore' ); $I->canSeeThePageInLanguage( 'it-IT' ); - $I->seeAdminSuccessNotice( 'Switched to Autore' ); + $I->seeAdminSuccessNotice( 'Switched to Autore.' ); $I->canSeeTheElementInLanguage( '#user_switching p', 'en-US' ); $I->amOnAdminPage( '/' ); $I->switchBackTo( 'admin' ); $I->canSeeThePageInLanguage( 'en-US' ); - $I->seeAdminSuccessNotice( 'Switched back to admin' ); + $I->seeAdminSuccessNotice( 'Switched back to admin.' ); } } diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index 657dee4..acfc81b 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -34,7 +34,7 @@ public function SwitchOffFromDashboardAndBackFromLoginScreen( AcceptanceTester $ $I->amOnPage( 'wp-login.php' ); $I->switchBackTo( 'admin' ); $I->seeCurrentUrlEquals( '/wp-admin/users.php?user_switched=true&switched_back=true' ); - $I->seeAdminSuccessNotice( 'Switched back to admin (admin)' ); + $I->seeAdminSuccessNotice( 'Switched back to admin.' ); $I->amLoggedInAs( 'admin' ); } diff --git a/tests/acceptance/SwitchToEnglishCest.php b/tests/acceptance/SwitchToEnglishCest.php index 8a56116..67fdd35 100644 --- a/tests/acceptance/SwitchToEnglishCest.php +++ b/tests/acceptance/SwitchToEnglishCest.php @@ -30,12 +30,12 @@ public function SwitchFromItalianAdminToEnglishAuthorAndBack( AcceptanceTester $ $I->loginAs( 'admin_it', 'admin_it' ); $I->switchToUser( 'author_en' ); $I->canSeeThePageInLanguage( 'en-US' ); - $I->seeAdminSuccessNotice( 'Cambiato a Author EN' ); + $I->seeAdminSuccessNotice( 'Cambiato a Author EN.' ); $I->canSeeTheElementInLanguage( '#user_switching p', 'it-IT' ); $I->amOnAdminPage( '/' ); $I->switchBackTo( 'admin_it' ); $I->canSeeThePageInLanguage( 'it-IT' ); - $I->seeAdminSuccessNotice( 'Tornato a Admin IT' ); + $I->seeAdminSuccessNotice( 'Tornato a Admin IT.' ); } } diff --git a/tests/acceptance/SwitchUserCest.php b/tests/acceptance/SwitchUserCest.php index 67816a8..b8d52fd 100644 --- a/tests/acceptance/SwitchUserCest.php +++ b/tests/acceptance/SwitchUserCest.php @@ -18,7 +18,7 @@ public function SwitchToEditorThenBackFromFrontEnd( AcceptanceTester $I ) { $I->switchToUser( 'editor' ); $I->seeCurrentUrlEquals( '/wp-admin/?user_switched=true' ); - $I->seeAdminSuccessNotice( 'Switched to editor' ); + $I->seeAdminSuccessNotice( 'Switched to editor.' ); $I->amLoggedInAs( 'editor' ); $I->amOnPage( '/' ); @@ -33,13 +33,13 @@ public function SwitchToEditorThenBackFromAdminArea( AcceptanceTester $I ) { $I->switchToUser( 'editor' ); $I->seeCurrentUrlEquals( '/wp-admin/?user_switched=true' ); - $I->seeAdminSuccessNotice( 'Switched to editor' ); + $I->seeAdminSuccessNotice( 'Switched to editor.' ); $I->amLoggedInAs( 'editor' ); $I->amOnAdminPage( 'tools.php' ); $I->switchBackTo( 'admin' ); $I->seeCurrentUrlEquals( '/wp-admin/tools.php?user_switched=true&switched_back=true' ); - $I->seeAdminSuccessNotice( 'Switched back to admin' ); + $I->seeAdminSuccessNotice( 'Switched back to admin.' ); $I->amLoggedInAs( 'admin' ); } } diff --git a/user-switching.php b/user-switching.php index 04d832f..dc310d5 100644 --- a/user-switching.php +++ b/user-switching.php @@ -427,12 +427,7 @@ public function action_admin_notices() { $message = ''; $just_switched = isset( $_GET['user_switched'] ); if ( $just_switched ) { - $message = esc_html( sprintf( - /* Translators: 1: user display name; 2: username; */ - __( 'Switched to %1$s (%2$s).', 'user-switching' ), - $user->display_name, - $user->user_login - ) ); + $message = esc_html( self::switched_to_message( $user ) ); } $switch_back_url = add_query_arg( array( 'redirect_to' => urlencode( self::current_url() ), @@ -441,12 +436,7 @@ public function action_admin_notices() { $message .= sprintf( ' %s.', esc_url( $switch_back_url ), - esc_html( sprintf( - /* Translators: 1: user display name; 2: username; */ - __( 'Switch back to %1$s (%2$s)', 'user-switching' ), - $old_user->display_name, - $old_user->user_login - ) ) + esc_html( self::switch_back_message( $old_user ) ) ); /** @@ -480,19 +470,9 @@ public function action_admin_notices() {

display_name, - $user->user_login - ) ); + echo esc_html( self::switched_back_message( $user ) ); } else { - echo esc_html( sprintf( - /* Translators: 1: user display name; 2: username; */ - __( 'Switched to %1$s (%2$s).', 'user-switching' ), - $user->display_name, - $user->user_login - ) ); + echo esc_html( self::switched_to_message( $user ) ); } ?>

@@ -565,12 +545,7 @@ public function action_admin_bar_menu( WP_Admin_Bar $wp_admin_bar ) { $wp_admin_bar->add_node( array( 'parent' => $parent, 'id' => 'switch-back', - 'title' => esc_html( sprintf( - /* Translators: 1: user display name; 2: username; */ - __( 'Switch back to %1$s (%2$s)', 'user-switching' ), - $old_user->display_name, - $old_user->user_login - ) ), + 'title' => esc_html( self::switch_back_message( $old_user ) ), 'href' => add_query_arg( array( 'redirect_to' => urlencode( self::current_url() ), ), self::switch_back_url( $old_user ) ), @@ -601,12 +576,7 @@ public function action_admin_bar_menu( WP_Admin_Bar $wp_admin_bar ) { $wp_admin_bar->add_node( array( 'parent' => 'edit', 'id' => 'author-switch-back', - 'title' => esc_html( sprintf( - /* Translators: 1: user display name; 2: username; */ - __( 'Switch back to %1$s (%2$s)', 'user-switching' ), - $old_user->display_name, - $old_user->user_login - ) ), + 'title' => esc_html( self::switch_back_message( $old_user ) ), 'href' => add_query_arg( array( 'redirect_to' => urlencode( self::current_url() ), ), self::switch_back_url( $old_user ) ), @@ -666,19 +636,13 @@ public function action_wp_meta() { $old_user = self::get_old_user(); if ( $old_user instanceof WP_User ) { - $link = sprintf( - /* Translators: 1: user display name; 2: username; */ - __( 'Switch back to %1$s (%2$s)', 'user-switching' ), - $old_user->display_name, - $old_user->user_login - ); $url = add_query_arg( array( 'redirect_to' => urlencode( self::current_url() ), ), self::switch_back_url( $old_user ) ); printf( '
  • %s
  • ', esc_url( $url ), - esc_html( $link ) + esc_html( self::switch_back_message( $old_user ) ) ); } } @@ -707,19 +671,13 @@ public function action_wp_footer() { $old_user = self::get_old_user(); if ( $old_user instanceof WP_User ) { - $link = sprintf( - /* Translators: 1: user display name; 2: username; */ - __( 'Switch back to %1$s (%2$s)', 'user-switching' ), - $old_user->display_name, - $old_user->user_login - ); $url = add_query_arg( array( 'redirect_to' => urlencode( self::current_url() ), ), self::switch_back_url( $old_user ) ); printf( '

    %s

    ', esc_url( $url ), - esc_html( $link ) + esc_html( self::switch_back_message( $old_user ) ) ); } } @@ -734,12 +692,6 @@ public function filter_login_message( $message ) { $old_user = self::get_old_user(); if ( $old_user instanceof WP_User ) { - $link = sprintf( - /* Translators: 1: user display name; 2: username; */ - __( 'Switch back to %1$s (%2$s)', 'user-switching' ), - $old_user->display_name, - $old_user->user_login - ); $url = self::switch_back_url( $old_user ); if ( ! empty( $_REQUEST['interim-login'] ) ) { @@ -757,7 +709,7 @@ public function filter_login_message( $message ) { $message .= sprintf( '%2$s', esc_url( $url ), - esc_html( $link ) + esc_html( self::switch_back_message( $old_user ) ) ); $message .= '

    '; } @@ -953,6 +905,69 @@ public static function switch_off_url( WP_User $user ) { ), wp_login_url() ), "switch_off_{$user->ID}" ); } + /** + * Returns the message shown to the user when they've switched to a user. + * + * @param WP_User $user The concerned user. + * @return string The message. + */ + public static function switched_to_message( WP_User $user ) { + $message = sprintf( + /* Translators: 1: user display name; 2: username; */ + __( 'Switched to %1$s (%2$s).', 'user-switching' ), + $user->display_name, + $user->user_login + ); + + // Removes the user login from this message without invalidating existing translations + return str_replace( sprintf( + ' (%s)', + $user->user_login + ), '', $message ); + } + + /** + * Returns the message shown to the user for the link to switch back to their original user. + * + * @param WP_User $user The concerned user. + * @return string The message. + */ + public static function switch_back_message( WP_User $user ) { + $message = sprintf( + /* Translators: 1: user display name; 2: username; */ + __( 'Switch back to %1$s (%2$s)', 'user-switching' ), + $user->display_name, + $user->user_login + ); + + // Removes the user login from this message without invalidating existing translations + return str_replace( sprintf( + ' (%s)', + $user->user_login + ), '', $message ); + } + + /** + * Returns the message shown to the user when they've switched back to their original user. + * + * @param WP_User $user The concerned user. + * @return string The message. + */ + public static function switched_back_message( WP_User $user ) { + $message = sprintf( + /* Translators: 1: user display name; 2: username; */ + __( 'Switched back to %1$s (%2$s).', 'user-switching' ), + $user->display_name, + $user->user_login + ); + + // Removes the user login from this message without invalidating existing translations + return str_replace( sprintf( + ' (%s)', + $user->user_login + ), '', $message ); + } + /** * Returns the current URL. * @@ -1047,12 +1062,7 @@ public function filter_woocommerce_account_menu_items( array $items ) { return $items; } - $items['user-switching-switch-back'] = sprintf( - /* Translators: 1: user display name; 2: username; */ - __( 'Switch back to %1$s (%2$s)', 'user-switching' ), - $old_user->display_name, - $old_user->user_login - ); + $items['user-switching-switch-back'] = self::switch_back_message( $old_user ); return $items; } From e07ad1d71729da306227637d100904c3532d9f94 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 30 Jul 2022 12:20:19 +0100 Subject: [PATCH 186/270] Apply basic styling to the Switch Back link that appears in the footer. --- user-switching.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user-switching.php b/user-switching.php index dc310d5..fabe06e 100644 --- a/user-switching.php +++ b/user-switching.php @@ -675,7 +675,7 @@ public function action_wp_footer() { 'redirect_to' => urlencode( self::current_url() ), ), self::switch_back_url( $old_user ) ); printf( - '

    %s

    ', + '

    %s

    ', esc_url( $url ), esc_html( self::switch_back_message( $old_user ) ) ); From 7a0f23cdfe0b9e7e37f3d44525d8bd98511983ef Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 30 Jul 2022 12:20:41 +0100 Subject: [PATCH 187/270] Version 1.7.0. --- package.json | 2 +- readme.md | 2 +- user-switching.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index f5bee00..57212df 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "user-switching", - "version": "1.6.0", + "version": "1.7.0", "description": "Instant switching between user accounts in WordPress.", "license": "GPL-2.0-or-later", "author": "John Blackbourn", diff --git a/readme.md b/readme.md index a3289bc..18eaece 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ # User Switching -Stable tag: 1.6.0 +Stable tag: 1.7.0 Requires at least: 3.7 Tested up to: 6.0 Requires PHP: 5.3 diff --git a/user-switching.php b/user-switching.php index fabe06e..9361eb8 100644 --- a/user-switching.php +++ b/user-switching.php @@ -10,7 +10,7 @@ * * Plugin Name: User Switching * Description: Instant switching between user accounts in WordPress - * Version: 1.6.0 + * Version: 1.7.0 * Plugin URI: https://wordpress.org/plugins/user-switching/ * Author: John Blackbourn & contributors * Author URI: https://github.com/johnbillion/user-switching/graphs/contributors @@ -381,7 +381,7 @@ protected static function get_redirect( WP_User $new_user = null, WP_User $old_u /** * Filters the redirect location after a user switches to another account or switches off. * - * @since x.y.z + * @since 1.7.0 * * @param string $redirect_to The target redirect location, or an empty string if none is specified. * @param string|null $redirect_type The redirect type, see the `user_switching::REDIRECT_*` constants. From d66b01f9b6a791c8725b51328e5ca3936460dcab Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 30 Jul 2022 12:52:57 +0100 Subject: [PATCH 188/270] Docs! --- CONTRIBUTING.md | 7 +------ readme.md | 3 ++- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bd3c6d1..df39be1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,7 +35,6 @@ You can clone this repo and activate it like a normal WordPress plugin. If you w ### Prerequisites * [Composer](https://getcomposer.org/) -* [Node](https://nodejs.org/) * A local installation of MariaDB or MySQL ### Setup @@ -44,11 +43,7 @@ You can clone this repo and activate it like a normal WordPress plugin. If you w composer install -2. Install the Node dependencies: - - npm install - -3. Check the MySQL database credentials in the `tests/.env` file and amend them as necessary. +2. Check the MySQL database credentials in the `tests/.env` file and amend them as necessary. **Important:** Ensure you use a separate test database (eg. `wordpress_test`) because, just like the WordPress test suite, the database will be wiped clean with every test run. diff --git a/readme.md b/readme.md index 18eaece..8ca6e6d 100644 --- a/readme.md +++ b/readme.md @@ -35,7 +35,8 @@ This plugin allows you to quickly swap between user accounts in WordPress at the * Uses the cookie authentication system in WordPress when remembering the account(s) you've switched from and when switching back. * Implements the nonce security system in WordPress, meaning only those who intend to switch users can switch. * Full support for user session validation where appropriate. - * Full support for administration over SSL (if applicable). + * Full support for HTTPS. + * Approved for use on enterprise-grade WordPress platforms such as Altis and WordPress.com VIP. ### Usage From d5f52f82147d8bd89c98b96696371c1a62897fec Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 30 Jul 2022 15:40:07 +0100 Subject: [PATCH 189/270] More docs. --- readme.md | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 8ca6e6d..c03f3bf 100644 --- a/readme.md +++ b/readme.md @@ -82,7 +82,11 @@ Yes, it's actively tested and working up to PHP 8.1. Switching off logs you out of your account but retains your user ID in an authentication cookie so you can switch straight back without having to log in again manually. It's akin to switching to no user, and being able to switch back. -The *Switch Off* link can be found in your profile menu in the WordPress toolbar. Once you've switched off you'll see a *Switch back* link on the Log In screen and in the footer of your site. +The *Switch Off* link can be found in your profile menu in the WordPress toolbar. Once you've switched off you'll see a *Switch back* link in a few places: + +* In the footer of your site +* On the Log In screen +* In the "Meta" widget ### Does this plugin work with WordPress Multisite? @@ -178,7 +182,7 @@ if ( method_exists( 'user_switching', 'get_old_user' ) ) { ### Can I determine whether the current user switched into their account? -Yes. Use the `current_user_switched()` function for this. +Yes. Use the `current_user_switched()` function for this. If the current user switched into their account from another then it returns a `WP_User` object for their originating user, otherwise it returns false. ~~~php if ( function_exists( 'current_user_switched' ) ) { @@ -194,7 +198,7 @@ if ( function_exists( 'current_user_switched' ) ) { Potentially yes, but User Switching includes some safety protections for this and there are further precautions you can take as a site administrator: -* User Switching stores the ID of the originating user in the new session for the user they switch to. Although this session does not persist by default when they subsequently switch back, there will be a record of this ID if your MySQL server has query logging enabled. +* User Switching stores the ID of the originating user in the new WordPress user session for the user they switch to. Although this session does not persist by default when they subsequently switch back, there will be a record of this ID if your database server has query logging enabled. * User Switching stores the login name of the originating user in an authentication cookie (see the Privacy Statement for more information). If your server access logs store cookie data, there will be a record of this login name (along with the IP address) for each access request. * You can install an audit trail plugin such as Simple History, WP Activity Log, or Stream, all of which have built-in support for User Switching and all of which log an entry when a user switches into another account. * User Switching triggers an action when a user switches account, switches off, or switches back (see below). You can use these actions to perform additional logging for safety purposes depending on your requirements. @@ -265,6 +269,22 @@ When a user switches off, the `switch_off_user` hook is called: do_action( 'switch_off_user', $old_user_id, $old_token ); ~~~ +When a user switches to another account, switches off, or switches back, the `user_switching_redirect_to` filter is applied to the location that they get redirected to: + +~~~php +/** + * Filters the redirect location after a user switches to another account or switches off. + * + * @since 1.7.0 + * + * @param string $redirect_to The target redirect location, or an empty string if none is specified. + * @param string|null $redirect_type The redirect type, see the `user_switching::REDIRECT_*` constants. + * @param WP_User|null $new_user The user being switched to, or null if there is none. + * @param WP_User|null $old_user The user being switched from, or null if there is none. + */ +return apply_filters( 'user_switching_redirect_to', $redirect_to, $redirect_type, $new_user, $old_user ); +~~~ + In addition, User Switching respects the following filters from WordPress core when appropriate: * `login_redirect` when switching to another user. From 3eac8a96476a46bf1ef43ceda394071b2d4640e5 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 30 Jul 2022 15:40:27 +0100 Subject: [PATCH 190/270] Always set the redirect type even if the target object isn't compliant. --- user-switching.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/user-switching.php b/user-switching.php index 9361eb8..bd8e446 100644 --- a/user-switching.php +++ b/user-switching.php @@ -309,6 +309,7 @@ protected static function get_redirect( WP_User $new_user = null, WP_User $old_u } elseif ( ! empty( $_GET['redirect_to_post'] ) ) { // Post $post_id = absint( $_GET['redirect_to_post'] ); + $redirect_type = self::REDIRECT_TYPE_POST; if ( function_exists( 'is_post_publicly_viewable' ) && is_post_publicly_viewable( $post_id ) ) { $link = get_permalink( $post_id ); @@ -316,12 +317,12 @@ protected static function get_redirect( WP_User $new_user = null, WP_User $old_u if ( is_string( $link ) ) { $redirect_to = $link; $requested_redirect_to = $link; - $redirect_type = self::REDIRECT_TYPE_POST; } } } elseif ( ! empty( $_GET['redirect_to_term'] ) ) { // Term $term = get_term( absint( $_GET['redirect_to_term'] ) ); + $redirect_type = self::REDIRECT_TYPE_TERM; if ( ( $term instanceof WP_Term ) && function_exists( 'is_taxonomy_viewable' ) && is_taxonomy_viewable( $term->taxonomy ) ) { $link = get_term_link( $term ); @@ -329,12 +330,12 @@ protected static function get_redirect( WP_User $new_user = null, WP_User $old_u if ( is_string( $link ) ) { $redirect_to = $link; $requested_redirect_to = $link; - $redirect_type = self::REDIRECT_TYPE_TERM; } } } elseif ( ! empty( $_GET['redirect_to_user'] ) ) { // User $user = get_userdata( absint( $_GET['redirect_to_user'] ) ); + $redirect_type = self::REDIRECT_TYPE_USER; if ( $user instanceof WP_User ) { $link = get_author_posts_url( $user->ID ); @@ -342,12 +343,12 @@ protected static function get_redirect( WP_User $new_user = null, WP_User $old_u if ( is_string( $link ) ) { $redirect_to = $link; $requested_redirect_to = $link; - $redirect_type = self::REDIRECT_TYPE_USER; } } } elseif ( ! empty( $_GET['redirect_to_comment'] ) ) { // Comment $comment = get_comment( absint( $_GET['redirect_to_comment'] ) ); + $redirect_type = self::REDIRECT_TYPE_COMMENT; if ( $comment instanceof WP_Comment ) { if ( 'approved' === wp_get_comment_status( $comment ) ) { @@ -356,7 +357,6 @@ protected static function get_redirect( WP_User $new_user = null, WP_User $old_u if ( is_string( $link ) ) { $redirect_to = $link; $requested_redirect_to = $link; - $redirect_type = self::REDIRECT_TYPE_COMMENT; } } elseif ( function_exists( 'is_post_publicly_viewable' ) && is_post_publicly_viewable( (int) $comment->comment_post_ID ) ) { $link = get_permalink( (int) $comment->comment_post_ID ); @@ -364,7 +364,6 @@ protected static function get_redirect( WP_User $new_user = null, WP_User $old_u if ( is_string( $link ) ) { $redirect_to = $link; $requested_redirect_to = $link; - $redirect_type = self::REDIRECT_TYPE_POST; } } } From 21eb04833d57bba667365f05924403abbfdda0b5 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 24 Aug 2022 23:35:38 +0100 Subject: [PATCH 191/270] Use latest Ubuntu in the test runs. --- .github/workflows/coding-standards.yml | 2 +- .github/workflows/deploy-assets.yml | 2 +- .github/workflows/deploy-tag.yml | 2 +- .github/workflows/e2e.yml | 2 +- .github/workflows/test.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 4f9fbec..609ed69 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -26,7 +26,7 @@ on: jobs: build: name: PHP Coding Standards - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest timeout-minutes: 10 steps: - name: Checkout repository diff --git a/.github/workflows/deploy-assets.yml b/.github/workflows/deploy-assets.yml index d692aeb..268da33 100644 --- a/.github/workflows/deploy-assets.yml +++ b/.github/workflows/deploy-assets.yml @@ -9,7 +9,7 @@ on: jobs: wordpress: name: WordPress.org - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest timeout-minutes: 10 steps: - name: Checkout repository diff --git a/.github/workflows/deploy-tag.yml b/.github/workflows/deploy-tag.yml index 2e30cf1..5a54230 100644 --- a/.github/workflows/deploy-tag.yml +++ b/.github/workflows/deploy-tag.yml @@ -8,7 +8,7 @@ on: jobs: wordpress: name: WordPress.org - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest timeout-minutes: 10 steps: - name: Checkout repository diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index d581376..e526e41 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -41,7 +41,7 @@ jobs: wp: '4.7' fail-fast: false name: "WP ${{ matrix.wp }} / PHP ${{ matrix.php }}" - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest timeout-minutes: 10 steps: - name: Checkout repository diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a1585de..5ad7074 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -39,7 +39,7 @@ jobs: wp: '4.9' fail-fast: false name: "WP ${{ matrix.wp }} / PHP ${{ matrix.php }}" - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest timeout-minutes: 10 steps: - name: Checkout repository From 6cf336ab3f77f46d4bf71a1952843b7e9e5fc18f Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 24 Aug 2022 23:36:15 +0100 Subject: [PATCH 192/270] Show PHP errors when possible during CI. --- .github/workflows/coding-standards.yml | 1 + .github/workflows/e2e.yml | 1 + .github/workflows/test.yml | 1 + 3 files changed, 3 insertions(+) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 609ed69..1f8667b 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -60,6 +60,7 @@ jobs: with: php-version: '8.0' coverage: none + ini-file: development env: fail-fast: true diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index e526e41..a68e7dd 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -64,6 +64,7 @@ jobs: with: php-version: ${{ matrix.php }} extensions: mysqli, xmlwriter, xdebug + ini-file: development ini-values: xdebug.mode="develop" env: fail-fast: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5ad7074..68a2a7d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -63,6 +63,7 @@ jobs: php-version: ${{ matrix.php }} extensions: mysqli, xmlwriter coverage: none + ini-file: development env: fail-fast: true From b704c54cc29b5eb02a95b7c617413856fa7c99d4 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 24 Aug 2022 23:36:54 +0100 Subject: [PATCH 193/270] Fix this number of accepted args. --- user-switching.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user-switching.php b/user-switching.php index bd8e446..1781baa 100644 --- a/user-switching.php +++ b/user-switching.php @@ -74,7 +74,7 @@ public function init_hooks() { add_filter( 'login_message', array( $this, 'filter_login_message' ), 1 ); add_filter( 'removable_query_args', array( $this, 'filter_removable_query_args' ) ); add_action( 'wp_meta', array( $this, 'action_wp_meta' ) ); - add_filter( 'plugin_row_meta', array( $this, 'filter_plugin_row_meta' ), 10, 4 ); + add_filter( 'plugin_row_meta', array( $this, 'filter_plugin_row_meta' ), 10, 2 ); add_action( 'wp_footer', array( $this, 'action_wp_footer' ) ); add_action( 'personal_options', array( $this, 'action_personal_options' ) ); add_action( 'admin_bar_menu', array( $this, 'action_admin_bar_menu' ), 11 ); From cd359bdb8e07c354fb14808e19434cc976d23713 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 15 Nov 2022 13:05:16 +0000 Subject: [PATCH 194/270] Pin phpstan-wordpress to 1.1.3 for now. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index d6e086f..6a6cda2 100644 --- a/composer.json +++ b/composer.json @@ -43,7 +43,7 @@ "phpstan/phpstan-phpunit": "^1.0", "roots/wordpress-core-installer": "^1.0.0", "roots/wordpress-full": "*", - "szepeviktor/phpstan-wordpress": "^1.0", + "szepeviktor/phpstan-wordpress": "1.1.3", "vlucas/phpdotenv": "^3", "wp-cli/core-command": "^2", "wp-cli/db-command": "^2", From ccbc248a1e5f9db44e207f7113c96dbe409c14ac Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 15 Nov 2022 13:05:26 +0000 Subject: [PATCH 195/270] Increase the memory limit for PHPStan. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 6a6cda2..706591f 100644 --- a/composer.json +++ b/composer.json @@ -65,7 +65,7 @@ "phpcs -nps --colors --report-code --report-summary --report-width=80 --cache=tests/cache/phpcs.json ." ], "test:phpstan": [ - "phpstan analyze" + "phpstan analyze --memory-limit=1024M" ], "test:integration": [ "codecept run integration --env singlesite --skip-group ms-required", From 7dda843de32b947b399b1f747b958a07dc23dd8e Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 8 Dec 2022 19:33:20 +0100 Subject: [PATCH 196/270] Run CI testing on PHP 8.2. --- .github/workflows/e2e.yml | 2 +- .github/workflows/test.yml | 2 +- readme.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index a68e7dd..46a729b 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -33,7 +33,7 @@ jobs: build: strategy: matrix: - php: ['8.1','8.0','7.4','5.6'] + php: ['8.2.','8.1','8.0','7.4','5.6'] wp: ['latest', 'nightly'] include: # Oldest version that supports user locales: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 68a2a7d..55963d4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: build: strategy: matrix: - php: ['8.1','8.0','7.4','5.6'] + php: ['8.2','8.1','8.0','7.4','5.6'] wp: ['latest', 'nightly'] include: # Oldest version that passes the `$token` parameter to session actions: diff --git a/readme.md b/readme.md index c03f3bf..fca03ac 100644 --- a/readme.md +++ b/readme.md @@ -76,7 +76,7 @@ See also the FAQ for some questions relating to privacy and safety when switchin ### Does this plugin work with PHP 8? -Yes, it's actively tested and working up to PHP 8.1. +Yes, it's actively tested and working up to PHP 8.2. ### What does "Switch off" mean? From 01ef97043b957be8e70e139aedb4bdec45f743cd Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 16 Mar 2023 22:15:46 +0100 Subject: [PATCH 197/270] Add an accessibility statement. --- readme.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/readme.md b/readme.md index c03f3bf..1647c16 100644 --- a/readme.md +++ b/readme.md @@ -65,6 +65,12 @@ User Switching does not send data to any third party, nor does it include any th See also the FAQ for some questions relating to privacy and safety when switching between users. +### Accessibility Statement + +User Switching aims to be fully accessible to all of its users. It implements best practices for web accessibility, outputs semantic and structured markup, adheres to the default styles and accessibility guidelines of WordPress, uses the accessibility APIs provided by WordPress and web browsers where appropriate, and is fully accessible via keyboard. + +User Switching should adhere to Web Content Accessibility Guidelines (WCAG) 2.0 at level AA when used with a recent version of WordPress where its admin area itself adheres to these guidelines. If you've experienced or identified an accessibility issue in User Switching, please open a thread in [the User Switching plugin support forum](https://wordpress.org/support/plugin/user-switching/) and I'll address it swiftly. + ## Screenshots 1. The *Switch To* link on the Users screen From 235fc4a7c4d54bf425e931c28ac6eaf33f1991da Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 18 Mar 2023 16:04:21 +0100 Subject: [PATCH 198/270] Prevent deprecated errors caused by WordPress Coding Standards not supporting PHP 8.0+. --- phpcs.xml.dist | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 480f544..37b2ebb 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -3,6 +3,12 @@ + + + */.github/* */build/* */features/* From e6d16ad6f21dec1d68564fdaf7875e5a483b0f67 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 18 Mar 2023 16:06:59 +0100 Subject: [PATCH 199/270] Trim the PHP test versions to latest minor in each major branch. --- .github/workflows/e2e.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 46a729b..cfe2753 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -33,7 +33,7 @@ jobs: build: strategy: matrix: - php: ['8.2.','8.1','8.0','7.4','5.6'] + php: ['8.2','7.4','5.6'] wp: ['latest', 'nightly'] include: # Oldest version that supports user locales: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 55963d4..6635584 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: build: strategy: matrix: - php: ['8.2','8.1','8.0','7.4','5.6'] + php: ['8.2','7.4','5.6'] wp: ['latest', 'nightly'] include: # Oldest version that passes the `$token` parameter to session actions: From 41b8d03cc743c21dcf06f1049875c93205b80ad0 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 18 Mar 2023 16:07:38 +0100 Subject: [PATCH 200/270] Update some actions. --- .github/workflows/coding-standards.yml | 5 +++-- .github/workflows/deploy-assets.yml | 2 +- .github/workflows/deploy-tag.yml | 2 +- .github/workflows/e2e.yml | 5 +++-- .github/workflows/test.yml | 5 +++-- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 1f8667b..3e5e759 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -30,7 +30,7 @@ jobs: timeout-minutes: 10 steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Get Composer cache directory id: composer-cache @@ -56,13 +56,14 @@ jobs: key: 8.0-phpcs-${{ hashFiles('user-switching.php') }} - name: Install PHP - uses: shivammathur/setup-php@2.16.0 + uses: shivammathur/setup-php@v2 with: php-version: '8.0' coverage: none ini-file: development env: fail-fast: true + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Debugging run: | diff --git a/.github/workflows/deploy-assets.yml b/.github/workflows/deploy-assets.yml index 268da33..f83c189 100644 --- a/.github/workflows/deploy-assets.yml +++ b/.github/workflows/deploy-assets.yml @@ -13,7 +13,7 @@ jobs: timeout-minutes: 10 steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 # @TODO need to cache the npm dependencies - name: Install Dependencies diff --git a/.github/workflows/deploy-tag.yml b/.github/workflows/deploy-tag.yml index 5a54230..16d7dae 100644 --- a/.github/workflows/deploy-tag.yml +++ b/.github/workflows/deploy-tag.yml @@ -12,7 +12,7 @@ jobs: timeout-minutes: 10 steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 # @TODO need to cache the npm dependencies - name: Install Dependencies diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index cfe2753..04d0039 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -45,7 +45,7 @@ jobs: timeout-minutes: 10 steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Get Composer cache directory id: composer-cache @@ -60,7 +60,7 @@ jobs: key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} - name: Install PHP - uses: shivammathur/setup-php@2.16.0 + uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} extensions: mysqli, xmlwriter, xdebug @@ -68,6 +68,7 @@ jobs: ini-values: xdebug.mode="develop" env: fail-fast: true + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Debugging run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6635584..9d96177 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -43,7 +43,7 @@ jobs: timeout-minutes: 10 steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Get Composer cache directory id: composer-cache @@ -58,7 +58,7 @@ jobs: key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} - name: Install PHP - uses: shivammathur/setup-php@2.16.0 + uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} extensions: mysqli, xmlwriter @@ -66,6 +66,7 @@ jobs: ini-file: development env: fail-fast: true + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Debugging run: | From e716d81dde369914bf6c81e81adee5e841c8fd5d Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 18 Mar 2023 16:20:02 +0100 Subject: [PATCH 201/270] Scrap the path filtering for workflows. --- .github/workflows/coding-standards.yml | 12 ------------ .github/workflows/e2e.yml | 14 -------------- .github/workflows/test.yml | 12 ------------ 3 files changed, 38 deletions(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 3e5e759..3b99dd2 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -7,21 +7,9 @@ on: - 'develop' - 'trunk' - 'master' - paths: - - '.github/workflows/coding-standards.yml' - - 'composer.json' - - 'phpcs.xml.dist' - - 'phpstan.neon.dist' - - 'user-switching.php' pull_request: branches: - '**' - paths: - - '.github/workflows/coding-standards.yml' - - 'composer.json' - - 'phpcs.xml.dist' - - 'phpstan.neon.dist' - - 'user-switching.php' jobs: build: diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 04d0039..127c481 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -7,23 +7,9 @@ on: - 'develop' - 'trunk' - 'master' - paths: - - '.github/workflows/e2e.yml' - - 'codeception.dist.yml' - - 'bin/test.sh' - - 'composer.json' - - 'tests/**' - - 'user-switching.php' pull_request: branches: - '**' - paths: - - '.github/workflows/e2e.yml' - - 'codeception.dist.yml' - - 'bin/test.sh' - - 'composer.json' - - 'tests/**' - - 'user-switching.php' # Once weekly on Wednesdays at 06:00 UTC. schedule: - cron: '0 6 * * 3' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9d96177..1149f3d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,21 +7,9 @@ on: - 'develop' - 'trunk' - 'master' - paths: - - '.github/workflows/test.yml' - - 'composer.json' - - 'codeception.dist.yml' - - 'tests/**' - - 'user-switching.php' pull_request: branches: - '**' - paths: - - '.github/workflows/test.yml' - - 'composer.json' - - 'codeception.dist.yml' - - 'tests/**' - - 'user-switching.php' # Once weekly on Wednesdays at 05:00 UTC. schedule: - cron: '0 5 * * 3' From 43f0f1bd35c58fd34db5b25e11fa83f10b41b57c Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 18 Mar 2023 16:20:02 +0100 Subject: [PATCH 202/270] Scrap the path filtering for workflows. --- .github/workflows/coding-standards.yml | 12 ------------ .github/workflows/e2e.yml | 14 -------------- .github/workflows/test.yml | 12 ------------ 3 files changed, 38 deletions(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 1f8667b..e9dd315 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -7,21 +7,9 @@ on: - 'develop' - 'trunk' - 'master' - paths: - - '.github/workflows/coding-standards.yml' - - 'composer.json' - - 'phpcs.xml.dist' - - 'phpstan.neon.dist' - - 'user-switching.php' pull_request: branches: - '**' - paths: - - '.github/workflows/coding-standards.yml' - - 'composer.json' - - 'phpcs.xml.dist' - - 'phpstan.neon.dist' - - 'user-switching.php' jobs: build: diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index a68e7dd..62f7dfa 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -7,23 +7,9 @@ on: - 'develop' - 'trunk' - 'master' - paths: - - '.github/workflows/e2e.yml' - - 'codeception.dist.yml' - - 'bin/test.sh' - - 'composer.json' - - 'tests/**' - - 'user-switching.php' pull_request: branches: - '**' - paths: - - '.github/workflows/e2e.yml' - - 'codeception.dist.yml' - - 'bin/test.sh' - - 'composer.json' - - 'tests/**' - - 'user-switching.php' # Once weekly on Wednesdays at 06:00 UTC. schedule: - cron: '0 6 * * 3' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 68a2a7d..3b7f476 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,21 +7,9 @@ on: - 'develop' - 'trunk' - 'master' - paths: - - '.github/workflows/test.yml' - - 'composer.json' - - 'codeception.dist.yml' - - 'tests/**' - - 'user-switching.php' pull_request: branches: - '**' - paths: - - '.github/workflows/test.yml' - - 'composer.json' - - 'codeception.dist.yml' - - 'tests/**' - - 'user-switching.php' # Once weekly on Wednesdays at 05:00 UTC. schedule: - cron: '0 5 * * 3' From abe64196065fe6ee0eafd3f110e9dd857d7cef2a Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 18 Mar 2023 16:27:20 +0100 Subject: [PATCH 203/270] Test on 6.0 instead of 6.1 as https://core.trac.wordpress.org/ticket/57116 is yet to make its way into the 6.1 branch. --- .github/workflows/e2e.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 127c481..ff3cb34 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: php: ['8.2','7.4','5.6'] - wp: ['latest', 'nightly'] + wp: ['6.0', 'nightly'] include: # Oldest version that supports user locales: - php: '7.1' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1149f3d..405b798 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: php: ['8.2','7.4','5.6'] - wp: ['latest', 'nightly'] + wp: ['6.0', 'nightly'] include: # Oldest version that passes the `$token` parameter to session actions: - php: '7.2' From 13acc0412e5f0744008fdcca323bed7a2869eb2b Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 18 Mar 2023 16:57:44 +0100 Subject: [PATCH 204/270] Attempt to fix MySQL authentication issues. --- .github/workflows/e2e.yml | 11 +++++++++-- .github/workflows/test.yml | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 62f7dfa..fddce23 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -29,6 +29,15 @@ jobs: name: "WP ${{ matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-latest timeout-minutes: 10 + services: + mysql: + image: bitnami/mysql:8 + ports: + - 3306/tcp + env: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: wordpress_test + MYSQL_AUTHENTICATION_PLUGIN: mysql_native_password steps: - name: Checkout repository uses: actions/checkout@v2 @@ -64,14 +73,12 @@ jobs: - name: Install dependencies run: | - sudo systemctl start mysql.service composer remove \ "phpstan/*" \ szepeviktor/phpstan-wordpress \ --dev composer require --dev --update-with-dependencies --prefer-dist \ roots/wordpress-full="${{ matrix.wp == 'latest' && '*' || (matrix.wp == 'nightly' && 'dev-main' || format('~{0}.0', matrix.wp)) }}" - mysqladmin -uroot -proot create wordpress_test - name: Run the tests run: composer test:acceptance diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3b7f476..20c0061 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,6 +29,15 @@ jobs: name: "WP ${{ matrix.wp }} / PHP ${{ matrix.php }}" runs-on: ubuntu-latest timeout-minutes: 10 + services: + mysql: + image: bitnami/mysql:8 + ports: + - 3306/tcp + env: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: wordpress_test + MYSQL_AUTHENTICATION_PLUGIN: mysql_native_password steps: - name: Checkout repository uses: actions/checkout@v2 @@ -64,14 +73,12 @@ jobs: - name: Install dependencies run: | - sudo systemctl start mysql.service composer remove \ "phpstan/*" \ szepeviktor/phpstan-wordpress \ --dev composer require --dev --update-with-dependencies --prefer-dist \ roots/wordpress-full="${{ matrix.wp == 'latest' && '*' || (matrix.wp == 'nightly' && 'dev-main' || format('~{0}.0', matrix.wp)) }}" - mysqladmin -uroot -proot create wordpress_test - name: Run the tests run: composer test:integration From 0d7c184eda37ae4d7f9b06094ce22885efdaa3e2 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Fri, 23 Jun 2023 23:47:11 +0200 Subject: [PATCH 205/270] Start bringing over the plugin test infrastructure. --- .npmrc | 1 + .nvmrc | 1 + codeception.dist.yml | 11 +--- composer.json | 113 ++++++++++++++++++------------------ docker-compose.yml | 84 +++++++++++++++++++++++++++ package.json | 13 +++-- phpstan.neon.dist | 8 ++- tests/.env.dist | 4 -- tests/acceptance.suite.yml | 36 +++++++----- tests/integration.suite.yml | 17 +++--- tests/phpstan/stubs.php | 9 --- tests/wp-config.php | 45 -------------- 12 files changed, 188 insertions(+), 154 deletions(-) create mode 100644 .npmrc create mode 100644 .nvmrc create mode 100644 docker-compose.yml delete mode 100644 tests/.env.dist delete mode 100644 tests/wp-config.php diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..b6f27f1 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..3c03207 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +18 diff --git a/codeception.dist.yml b/codeception.dist.yml index 31e5659..40f2274 100644 --- a/codeception.dist.yml +++ b/codeception.dist.yml @@ -5,14 +5,5 @@ paths: support: tests/_support envs: tests/_envs actor_suffix: Tester -extensions: - enabled: - - Codeception\Extension\RunFailed - - tad\WPBrowser\Extension\Symlinker - config: - tad\WPBrowser\Extension\Symlinker: - mode: plugin - destination: - default: tests/wordpress/wp-content/plugins params: - - tests/.env + - env diff --git a/composer.json b/composer.json index 706591f..a8265e2 100644 --- a/composer.json +++ b/composer.json @@ -1,94 +1,97 @@ { "name": "johnbillion/user-switching", "description": "Instant switching between user accounts in WordPress.", - "homepage": "https://github.com/johnbillion/user-switching", - "type": "wordpress-plugin", "license": "GPL-2.0-or-later", + "type": "wordpress-plugin", "authors": [ { "name": "John Blackbourn", "homepage": "https://johnblackbourn.com/" } ], + "homepage": "https://github.com/johnbillion/user-switching", "support": { "issues": "https://github.com/johnbillion/user-switching/issues", "forum": "https://wordpress.org/support/plugin/user-switching", "source": "https://github.com/johnbillion/user-switching" }, - "config": { - "sort-packages": true, - "allow-plugins": { - "composer/installers": true, - "composer/package-versions-deprecated": true, - "dealerdirect/phpcodesniffer-composer-installer": true, - "roots/wordpress-core-installer": true + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/johnbillion" } - }, - "extra": { - "wordpress-install-dir": "tests/wordpress" - }, + ], "require": { "php": ">=5.3", "composer/installers": "^1 || ^2" }, "require-dev": { - "codeception/module-cli": "^1.0", + "codeception/module-asserts": "^1.0", "codeception/module-db": "^1.0", - "codeception/module-phpbrowser": "^1.0", - "dealerdirect/phpcodesniffer-composer-installer": "*", - "lucatume/wp-browser": "^3.0", - "phpcompatibility/php-compatibility": "^9", + "codeception/module-webdriver": "^1.0", + "codeception/util-universalframework": "^1.0", + "dealerdirect/phpcodesniffer-composer-installer": "0.7.2", + "ergebnis/composer-normalize": "^2", + "johnbillion/plugin-infrastructure": "dev-trunk", + "lucatume/wp-browser": "^3.0.21", + "phpcompatibility/phpcompatibility-wp": "2.1.4", "phpstan/phpstan": "^1.0", - "phpstan/phpstan-deprecation-rules": "^1.0", "phpstan/phpstan-phpunit": "^1.0", - "roots/wordpress-core-installer": "^1.0.0", - "roots/wordpress-full": "*", - "szepeviktor/phpstan-wordpress": "1.1.3", - "vlucas/phpdotenv": "^3", - "wp-cli/core-command": "^2", - "wp-cli/db-command": "^2", - "wp-cli/extension-command": "^2", - "wp-cli/language-command": "^2", - "wp-cli/rewrite-command": "^2", - "wp-coding-standards/wpcs": "^2" + "roots/wordpress": "*", + "squizlabs/php_codesniffer": "3.7.1", + "szepeviktor/phpstan-wordpress": "1.1.6", + "wp-coding-standards/wpcs": "2.3.0" }, "autoload-dev": { "psr-4": { - "UserSwitching\\Tests\\": "tests/wpunit" + "UserSwitching\\Tests\\": "tests/integration" } }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true, + "ergebnis/composer-normalize": true, + "roots/wordpress-core-installer": true, + "composer/installers": true + }, + "classmap-authoritative": true, + "preferred-install": "dist", + "prepend-autoloader": false, + "sort-packages": true + }, + "extra": { + "wordpress-install-dir": "vendor/roots/wordpress" + }, "scripts": { - "post-update-cmd": [ - "@php -r \"! file_exists( 'tests/.env' ) && copy( 'tests/.env.dist', 'tests/.env' );\"" + "test": [ + "@composer validate --strict --no-check-lock", + "@composer normalize --dry-run", + "@test:phpstan", + "@test:phpcs", + "@test:integration", + "@test:acceptance" ], - "test:phpcs": [ - "phpcs -nps --colors --report-code --report-summary --report-width=80 --cache=tests/cache/phpcs.json ." + "test:acceptance": [ + "acceptance-tests" ], - "test:phpstan": [ - "phpstan analyze --memory-limit=1024M" + "test:destroy": [ + "COMPOSE_PROJECT_NAME=user-switching docker-compose down --volumes --remove-orphans" ], "test:integration": [ - "codecept run integration --env singlesite --skip-group ms-required", - "codecept run integration --env multisite --skip-group ms-excluded" + "integration-tests" ], - "test:acceptance": [ - "bin/test.sh" + "test:phpcs": [ + "phpcs -nps --colors --report-code --report-summary --report-width=80 --cache=tests/cache/phpcs.json --basepath='./' ." ], - "test:composer": [ - "@composer validate --strict --no-check-lock" + "test:phpstan": [ + "codecept build", + "phpstan analyze --memory-limit=1024M" ], - "test": [ - "@test:composer", - "@test:phpcs", - "@test:phpstan", - "@test:integration", - "@test:acceptance" + "test:start": [ + "COMPOSE_PROJECT_NAME=user-switching docker-compose up -d" + ], + "test:stop": [ + "COMPOSE_PROJECT_NAME=user-switching docker-compose down" ] - }, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/johnbillion" - } - ] + } } diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..8d73e9f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,84 @@ +version: '3.1' + +services: + + server: + image: nginx:alpine + container_name: ${COMPOSE_PROJECT_NAME}-server + restart: always + ports: + - 80 + depends_on: + - php + volumes: + - ./vendor/johnbillion/plugin-infrastructure/tests/nginx.conf:/etc/nginx/templates/default.conf.template + - ./vendor/roots/wordpress:/var/www/html/:rw + - ./vendor/johnbillion/plugin-infrastructure/tests/wp-config.php:/var/www/html/wp-config.php + - ./:/var/www/html/wp-content/plugins/${COMPOSE_PROJECT_NAME}:rw + + php: + image: wordpressdevelop/php:${LOCAL_PHP-8.1}-fpm + container_name: ${COMPOSE_PROJECT_NAME}-php + restart: always + environment: + WORDPRESS_DB_HOST: database + WORDPRESS_DB_USER: pluginuser + WORDPRESS_DB_PASSWORD: pluginpass + WORDPRESS_DB_NAME: plugindb + WORDPRESS_DEBUG: ${LOCAL_WP_DEBUG-1} + depends_on: + - database + init: true + volumes: + - ./vendor/roots/wordpress:/var/www/html/:rw + - ./vendor/johnbillion/plugin-infrastructure/tests/wp-config.php:/var/www/html/wp-config.php + - ./vendor/johnbillion/plugin-infrastructure/tests/php-config.ini:/usr/local/etc/php/conf.d/php-config.ini + - ./:/var/www/html/wp-content/plugins/${COMPOSE_PROJECT_NAME}:rw + + database: + image: mariadb:10.5.8 + container_name: ${COMPOSE_PROJECT_NAME}-database + restart: always + ports: + - 3306 + environment: + MYSQL_DATABASE: plugindb + MYSQL_USER: pluginuser + MYSQL_PASSWORD: pluginpass + MYSQL_RANDOM_ROOT_PASSWORD: '1' + volumes: + - database:/var/lib/mysql:rw + + wpcli: + image: wordpressdevelop/cli:${LOCAL_PHP-8.1}-fpm + container_name: ${COMPOSE_PROJECT_NAME}-wpcli + environment: + WORDPRESS_DB_HOST: database + WORDPRESS_DB_USER: pluginuser + WORDPRESS_DB_PASSWORD: pluginpass + WORDPRESS_DB_NAME: plugindb + depends_on: + - database + - php + init: true + volumes: + - ./vendor/roots/wordpress:/var/www/:rw + - ./vendor/johnbillion/plugin-infrastructure/tests/wp-config.php:/var/www/wp-config.php + - ./vendor/johnbillion/plugin-infrastructure/tests/php-config.ini:/usr/local/etc/php/conf.d/php-config.ini + - ./:/var/www/wp-content/plugins/${COMPOSE_PROJECT_NAME}:rw + + chrome: + image: seleniarm/standalone-chromium + container_name: ${COMPOSE_PROJECT_NAME}-chrome + profiles: + - acceptance-tests + depends_on: + - server + ports: + - 4444 + extra_hosts: + - host.docker.internal:host-gateway + shm_size: 2gb + +volumes: + database: diff --git a/package.json b/package.json index 57212df..cc52cce 100644 --- a/package.json +++ b/package.json @@ -5,15 +5,16 @@ "license": "GPL-2.0-or-later", "author": "John Blackbourn", "repository": "johnbillion/user-switching", + "engines": { + "node": ">=18" + }, "devDependencies": { - "@actions/github": "^2", - "replace-in-file": "^5", - "semver": "^7", + "plugin-infrastructure": "file:vendor/johnbillion/plugin-infrastructure", "version-bump-prompt": "^6.1.0" }, "scripts": { - "bump:patch": "bump patch --commit 'Version %s.' user-switching.php package.json readme.md", - "bump:minor": "bump minor --commit 'Version %s.' user-switching.php package.json readme.md", - "bump:major": "bump major --commit 'Version %s.' user-switching.php package.json readme.md" + "bump:patch": "bump patch --commit 'Version %s.' user-switching.php package.json package-lock.json readme.md", + "bump:minor": "bump minor --commit 'Version %s.' user-switching.php package.json package-lock.json readme.md", + "bump:major": "bump major --commit 'Version %s.' user-switching.php package.json package-lock.json readme.md" } } diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 97af7cf..2b99e55 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,12 +1,16 @@ includes: - - vendor/phpstan/phpstan-deprecation-rules/rules.neon - vendor/phpstan/phpstan-phpunit/extension.neon - vendor/szepeviktor/phpstan-wordpress/extension.neon + - vendor/johnbillion/plugin-infrastructure/phpstan/extension.neon parameters: level: 9 - tmpDir: tests/cache paths: - user-switching.php + scanDirectories: + - tests/_support/ + excludePaths: + analyse: + - tests/integration/Supports/ bootstrapFiles: - tests/phpstan/stubs.php ignoreErrors: diff --git a/tests/.env.dist b/tests/.env.dist deleted file mode 100644 index cabbd93..0000000 --- a/tests/.env.dist +++ /dev/null @@ -1,4 +0,0 @@ -WP_TESTS_DB_NAME="wordpress_test" -WP_TESTS_DB_USER="root" -WP_TESTS_DB_PASS="root" -WP_TESTS_DB_HOST="localhost" diff --git a/tests/acceptance.suite.yml b/tests/acceptance.suite.yml index ebb5bc1..ff699da 100644 --- a/tests/acceptance.suite.yml +++ b/tests/acceptance.suite.yml @@ -1,29 +1,37 @@ # Codeception Test Suite Configuration # # Suite for acceptance tests. -# Perform tests in browser using WPBrowser. +# Perform tests in browser using WPWebDriver. actor: AcceptanceTester modules: enabled: + - WPWebDriver - WPDb - - WPCLI - - WPBrowser config: WPDb: - dsn: 'mysql:host=%WP_TESTS_DB_HOST%;dbname=%WP_TESTS_DB_NAME%' - user: '%WP_TESTS_DB_USER%' - password: '%WP_TESTS_DB_PASS%' + dsn: 'mysql:host=localhost:%TEST_SITE_DATABASE_PORT%;dbname=plugindb' + user: pluginuser + password: pluginpass url: '%TEST_SITE_WP_URL%' - tablePrefix: wp_ + tablePrefix: wp_acceptance_ dump: false populate: false cleanup: false - WPCLI: - path: '%TEST_SITE_WP_DIR%' + WPWebDriver: url: '%TEST_SITE_WP_URL%' - WPBrowser: - url: '%TEST_SITE_WP_URL%' - adminUsername: 'admin' - adminPassword: 'admin' - adminPath: '/wp-admin' + adminUsername: admin + adminPassword: admin + adminPath: /wp-admin + browser: chrome + host: localhost + port: '%TEST_SITE_WEBDRIVER_PORT%' + window_size: 1440x900 + capabilities: + chromeOptions: + args: [ + "--headless", + "--disable-gpu", + "--proxy-server='direct://'", + "--proxy-bypass-list=*" + ] diff --git a/tests/integration.suite.yml b/tests/integration.suite.yml index f1622d4..7abe0bb 100644 --- a/tests/integration.suite.yml +++ b/tests/integration.suite.yml @@ -8,15 +8,14 @@ modules: - WPLoader config: WPLoader: - wpRootFolder: tests/wordpress - dbName: '%WP_TESTS_DB_NAME%' - dbHost: '%WP_TESTS_DB_HOST%' - dbUser: '%WP_TESTS_DB_USER%' - dbPassword: '%WP_TESTS_DB_PASS%' - tablePrefix: wp_ - skipPluggables: true - plugins: ['user-switching/user-switching.php'] - activatePlugins: ['user-switching/user-switching.php'] + wpRootFolder: /var/www/html + dbName: plugindb + dbHost: database + dbUser: pluginuser + dbPassword: pluginpass + tablePrefix: wp_integration_ + plugins: ['%COMPOSE_PROJECT_NAME%/%COMPOSE_PROJECT_NAME%.php'] + activatePlugins: ['%COMPOSE_PROJECT_NAME%/%COMPOSE_PROJECT_NAME%.php'] env: singlesite: modules: diff --git a/tests/phpstan/stubs.php b/tests/phpstan/stubs.php index c108f60..3a58cd1 100644 --- a/tests/phpstan/stubs.php +++ b/tests/phpstan/stubs.php @@ -1,14 +1,5 @@ load(); -} - -// Disable debug mode as it can cause "headers already sent" if there are deprecations -define( 'WP_DEBUG', false ); - -// Prevent WP-Cron doing its thing during testing. -define( 'DISABLE_WP_CRON', true ); - -define( 'WP_PLUGIN_DIR', dirname( dirname( __DIR__ ) ) ); - -// WARNING WARNING WARNING! -// These tests will DROP ALL TABLES in the database with the prefix named below. -// DO NOT use a production database or one that is shared with something else. -define( 'DB_NAME', getenv( 'WP_TESTS_DB_NAME' ) ?: 'wordpress_test' ); -define( 'DB_USER', getenv( 'WP_TESTS_DB_USER' ) ?: 'root' ); -define( 'DB_PASSWORD', getenv( 'WP_TESTS_DB_PASS' ) ?: '' ); -define( 'DB_HOST', getenv( 'WP_TESTS_DB_HOST' ) ?: 'localhost' ); -define( 'DB_CHARSET', 'utf8' ); -define( 'DB_COLLATE', '' ); - -/** - * WordPress Database Table prefix. - * - * You can have multiple installations in one database if you give each - * a unique prefix. Only numbers, letters, and underscores please! - */ -$table_prefix = 'wp_'; - -/** Sets up WordPress vars and included files. */ -require_once ABSPATH . 'wp-settings.php'; From 4916242012c5cebf291c789807dd80a874af25d5 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Fri, 23 Jun 2023 23:47:41 +0200 Subject: [PATCH 206/270] Update the acceptance tests. --- tests/acceptance/Cest.php | 17 ----------------- tests/acceptance/SwitchFromEnglishCest.php | 4 +--- tests/acceptance/SwitchOffCest.php | 4 +--- tests/acceptance/SwitchToEnglishCest.php | 4 +--- tests/acceptance/SwitchUserCest.php | 4 +--- 5 files changed, 4 insertions(+), 29 deletions(-) delete mode 100644 tests/acceptance/Cest.php diff --git a/tests/acceptance/Cest.php b/tests/acceptance/Cest.php deleted file mode 100644 index ac62260..0000000 --- a/tests/acceptance/Cest.php +++ /dev/null @@ -1,17 +0,0 @@ -cli( 'db reset --yes' ); - - # Install WordPress: - $I->cli( 'core install --title="Example" --admin_user="admin" --admin_password="admin" --admin_email="admin@example.com" --skip-email' ); - $I->cli( 'rewrite structure "%postname%"' ); - - # Activate the plugin: - $I->cli( 'plugin activate user-switching' ); - } -} diff --git a/tests/acceptance/SwitchFromEnglishCest.php b/tests/acceptance/SwitchFromEnglishCest.php index 1ef50b8..7304a4a 100644 --- a/tests/acceptance/SwitchFromEnglishCest.php +++ b/tests/acceptance/SwitchFromEnglishCest.php @@ -3,10 +3,8 @@ * Acceptance tests for switching from a user who uses English to a user who doesn't */ -class SwitchFromEnglishCest extends Cest { +class SwitchFromEnglishCest { public function _before( AcceptanceTester $I ) { - parent::_before( $I ); - $I->comment( 'As an administrator of a site which uses more than one language' ); $I->comment( 'I need to be able to switch to user accounts that use a different language' ); $I->comment( 'And see the output of User Switching in my original language' ); diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index acfc81b..83f219d 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -3,10 +3,8 @@ * Acceptance tests for switching off. */ -class SwitchOffCest extends Cest { +class SwitchOffCest { public function _before( AcceptanceTester $I ) { - parent::_before( $I ); - $I->comment( 'As an administrator' ); $I->comment( 'I need to be able to switch off' ); $I->comment( 'In order to view the site without logging out completely' ); diff --git a/tests/acceptance/SwitchToEnglishCest.php b/tests/acceptance/SwitchToEnglishCest.php index 67fdd35..b1b5506 100644 --- a/tests/acceptance/SwitchToEnglishCest.php +++ b/tests/acceptance/SwitchToEnglishCest.php @@ -3,10 +3,8 @@ * Acceptance tests for switching from a user who doesn't use English to a user who does */ -class SwitchToEnglishCest extends Cest { +class SwitchToEnglishCest { public function _before( AcceptanceTester $I ) { - parent::_before( $I ); - $I->comment( 'As an administrator of a site which uses more than one language' ); $I->comment( 'I need to be able to switch between users' ); $I->comment( 'And see the output of User Switching in my original language' ); diff --git a/tests/acceptance/SwitchUserCest.php b/tests/acceptance/SwitchUserCest.php index b8d52fd..93cede6 100644 --- a/tests/acceptance/SwitchUserCest.php +++ b/tests/acceptance/SwitchUserCest.php @@ -3,10 +3,8 @@ * Acceptance tests for switching users. */ -class SwitchUserCest extends Cest { +class SwitchUserCest { public function _before( AcceptanceTester $I ) { - parent::_before( $I ); - $I->comment( 'As an administrator' ); $I->comment( 'I need to be able to switch between users' ); $I->comment( 'In order to access different user accounts' ); From 2d7167db3577ca3a1631fbb397b67e3db8c84826 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Fri, 23 Jun 2023 23:47:59 +0200 Subject: [PATCH 207/270] Update the GitHub Actions workflows. --- .github/workflows/acceptance-tests.yml | 34 ++++++++++ .github/workflows/changelog.js | 46 ------------- .github/workflows/coding-standards.yml | 70 ++++---------------- .github/workflows/deploy-assets.yml | 28 ++------ .github/workflows/deploy-tag.yml | 33 ++++------ .github/workflows/e2e.yml | 85 ------------------------- .github/workflows/integration-tests.yml | 35 ++++++++++ .github/workflows/test.yml | 78 ----------------------- 8 files changed, 100 insertions(+), 309 deletions(-) create mode 100644 .github/workflows/acceptance-tests.yml delete mode 100644 .github/workflows/changelog.js delete mode 100644 .github/workflows/e2e.yml create mode 100644 .github/workflows/integration-tests.yml delete mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml new file mode 100644 index 0000000..fa46fbf --- /dev/null +++ b/.github/workflows/acceptance-tests.yml @@ -0,0 +1,34 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow + +name: Acceptance Tests +on: + push: + branches: + - 'develop' + - 'trunk' + - 'master' + pull_request: + branches: + - '**' + # Once weekly on Thursdays at 08:00 UTC. + schedule: + - cron: '0 8 * * 4' + workflow_dispatch: + +jobs: + test: + name: WP ${{ matrix.wp }} / PHP ${{ matrix.php }} + strategy: + matrix: + wp: + - 'nightly' + - '6.2' + php: + - '8.2' + - '7.4' + - '5.6' + fail-fast: false + uses: johnbillion/plugin-infrastructure/.github/workflows/reusable-acceptance-tests.yml@trunk + with: + wp: ${{ matrix.wp }} + php: ${{ matrix.php }} diff --git a/.github/workflows/changelog.js b/.github/workflows/changelog.js deleted file mode 100644 index 92ff148..0000000 --- a/.github/workflows/changelog.js +++ /dev/null @@ -1,46 +0,0 @@ -const github = require('@actions/github'); -const semver = require('semver'); -const replace = require('replace-in-file'); - -const filename = process.argv[2] || 'readme.md'; -const myToken = process.env.TOKEN; - -async function run() { - const api = new github.GitHub(myToken); - - const { data: releases } = await api.repos.listReleases( github.context.repo ); - - let published = releases.filter( release => - ! release.draft && ! release.prerelease - ); - - let sorted = published.sort( ( a, b ) => - semver.rcompare( semver.coerce( a.tag_name ), semver.coerce( b.tag_name ) ) - ); - - let changelog = sorted.reduce( ( changelog, release ) => - `${changelog} - -### ${release.tag_name} ### - -${release.body}` - , '## Changelog ##' ); - - try { - const results = await replace( { - files: filename, - from: '', - to: changelog, - } ); - - if ( results.filter( result => ! result.hasChanged ).length ) { - console.error( 'No replacements made' ); - process.exitCode = 1; - } - } catch( exception ) { - console.error( exception ); - process.exitCode = 1; - } -} - -run(); diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 3b99dd2..d7f851e 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -10,62 +10,18 @@ on: pull_request: branches: - '**' + workflow_dispatch: jobs: - build: - name: PHP Coding Standards - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Get Composer cache directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Composer cache - uses: actions/cache@v2 - env: - cache-name: cache-composer-dependencies - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: 8.0-composer-${{ hashFiles('composer.json') }} - - - name: PHPCS and PHPStan cache - uses: actions/cache@v2 - env: - cache-name: cache-test-results - with: - path: tests/cache - # This uses the hash of user-switching.php in its cache key because Actions doesn't support - # always pulling in a cache file and simultaneously always updating it, unlike Travis. - # This way we always pull in a cache file and refresh it with each new version of the plugin. - key: 8.0-phpcs-${{ hashFiles('user-switching.php') }} - - - name: Install PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.0' - coverage: none - ini-file: development - env: - fail-fast: true - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Debugging - run: | - php --version - composer --version - - - name: Validate composer.json - run: composer test:composer - - - name: Install dependencies - run: | - composer install --prefer-dist - - - name: Run the tests - run: | - composer test:phpcs - composer test:phpstan + test: + name: PHP / PHP ${{ matrix.php }} + uses: johnbillion/plugin-infrastructure/.github/workflows/reusable-coding-standards.yml@trunk + strategy: + matrix: + php: + - '8.2' + - '7.4' + - '5.6' + fail-fast: false + with: + php: ${{ matrix.php }} diff --git a/.github/workflows/deploy-assets.yml b/.github/workflows/deploy-assets.yml index f83c189..5d899e7 100644 --- a/.github/workflows/deploy-assets.yml +++ b/.github/workflows/deploy-assets.yml @@ -9,24 +9,10 @@ on: jobs: wordpress: name: WordPress.org - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - # @TODO need to cache the npm dependencies - - name: Install Dependencies - run: npm install - - - name: Populate Changelog - run: node .github/workflows/changelog.js readme.md - env: - TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: WordPress Plugin Deploy - uses: 10up/action-wordpress-plugin-asset-update@1.4.1 - env: - SVN_USERNAME: ${{ secrets.WPORG_SVN_USERNAME }} - SVN_PASSWORD: ${{ secrets.WPORG_SVN_PASSWORD }} - README_NAME: readme.md + uses: johnbillion/plugin-infrastructure/.github/workflows/reusable-deploy-assets.yml@trunk + with: + plugin: user-switching + readme: readme.md + secrets: + WPORG_SVN_USERNAME: ${{ secrets.WPORG_SVN_USERNAME }} + WPORG_SVN_PASSWORD: ${{ secrets.WPORG_SVN_PASSWORD }} diff --git a/.github/workflows/deploy-tag.yml b/.github/workflows/deploy-tag.yml index 16d7dae..db9752d 100644 --- a/.github/workflows/deploy-tag.yml +++ b/.github/workflows/deploy-tag.yml @@ -5,26 +5,15 @@ on: release: types: [published] -jobs: - wordpress: - name: WordPress.org - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - # @TODO need to cache the npm dependencies - - name: Install Dependencies - run: npm install +concurrency: WordPress.org - - name: Populate Changelog - run: node .github/workflows/changelog.js readme.md - env: - TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: WordPress Plugin Deploy - uses: 10up/action-wordpress-plugin-deploy@1.4.1 - env: - SVN_USERNAME: ${{ secrets.WPORG_SVN_USERNAME }} - SVN_PASSWORD: ${{ secrets.WPORG_SVN_PASSWORD }} +jobs: + test: + name: Deploy Tag + uses: johnbillion/plugin-infrastructure/.github/workflows/reusable-deploy-tag.yml@trunk + with: + plugin: user-switching + readme: readme.md + secrets: + WPORG_SVN_USERNAME: ${{ secrets.WPORG_SVN_USERNAME }} + WPORG_SVN_PASSWORD: ${{ secrets.WPORG_SVN_PASSWORD }} diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml deleted file mode 100644 index ff3cb34..0000000 --- a/.github/workflows/e2e.yml +++ /dev/null @@ -1,85 +0,0 @@ -# yaml-language-server: $schema=https://json.schemastore.org/github-workflow - -name: Acceptance Tests -on: - push: - branches: - - 'develop' - - 'trunk' - - 'master' - pull_request: - branches: - - '**' - # Once weekly on Wednesdays at 06:00 UTC. - schedule: - - cron: '0 6 * * 3' - workflow_dispatch: - -jobs: - build: - strategy: - matrix: - php: ['8.2','7.4','5.6'] - wp: ['6.0', 'nightly'] - include: - # Oldest version that supports user locales: - - php: '7.1' - wp: '4.7' - fail-fast: false - name: "WP ${{ matrix.wp }} / PHP ${{ matrix.php }}" - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Get Composer cache directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Composer cache - uses: actions/cache@v2 - env: - cache-name: cache-composer-dependencies - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} - - - name: Install PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: mysqli, xmlwriter, xdebug - ini-file: development - ini-values: xdebug.mode="develop" - env: - fail-fast: true - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Debugging - run: | - php --version - php -m - composer --version - mysql --version - - - name: Install dependencies - run: | - sudo systemctl start mysql.service - composer remove \ - "phpstan/*" \ - szepeviktor/phpstan-wordpress \ - --dev - composer require --dev --update-with-dependencies --prefer-dist \ - roots/wordpress-full="${{ matrix.wp == 'latest' && '*' || (matrix.wp == 'nightly' && 'dev-main' || format('~{0}.0', matrix.wp)) }}" - mysqladmin -uroot -proot create wordpress_test - - - name: Run the tests - run: composer test:acceptance - - - name: Upload test artifacts - if: failure() - uses: actions/upload-artifact@v2 - with: - name: "acceptance-wp-${{ matrix.wp }}-php-${{ matrix.php }}" - path: tests/_output diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml new file mode 100644 index 0000000..6d502d5 --- /dev/null +++ b/.github/workflows/integration-tests.yml @@ -0,0 +1,35 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow + +name: Integration Tests +on: + push: + branches: + - 'develop' + - 'trunk' + - 'master' + pull_request: + branches: + - '**' + workflow_dispatch: + +jobs: + test: + name: WP ${{ matrix.wp }} / PHP ${{ matrix.php }} + uses: johnbillion/plugin-infrastructure/.github/workflows/reusable-integration-tests.yml@trunk + strategy: + matrix: + php: + - '8.2' + - '7.4' + wp: + - '*' + - 'dev-nightly' + dev: + - ${{ github.ref_name == 'develop' }} + exclude: + - wp: 'dev-nightly' + dev: false + fail-fast: false + with: + wp: ${{ matrix.wp }} + php: ${{ matrix.php }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 405b798..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,78 +0,0 @@ -# yaml-language-server: $schema=https://json.schemastore.org/github-workflow - -name: Integration Tests -on: - push: - branches: - - 'develop' - - 'trunk' - - 'master' - pull_request: - branches: - - '**' - # Once weekly on Wednesdays at 05:00 UTC. - schedule: - - cron: '0 5 * * 3' - workflow_dispatch: - -jobs: - build: - strategy: - matrix: - php: ['8.2','7.4','5.6'] - wp: ['6.0', 'nightly'] - include: - # Oldest version that passes the `$token` parameter to session actions: - - php: '7.2' - wp: '4.9' - fail-fast: false - name: "WP ${{ matrix.wp }} / PHP ${{ matrix.php }}" - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Get Composer cache directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Composer cache - uses: actions/cache@v2 - env: - cache-name: cache-composer-dependencies - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} - - - name: Install PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: mysqli, xmlwriter - coverage: none - ini-file: development - env: - fail-fast: true - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Debugging - run: | - php --version - php -m - composer --version - mysql --version - - - name: Install dependencies - run: | - sudo systemctl start mysql.service - composer remove \ - "phpstan/*" \ - szepeviktor/phpstan-wordpress \ - --dev - composer require --dev --update-with-dependencies --prefer-dist \ - roots/wordpress-full="${{ matrix.wp == 'latest' && '*' || (matrix.wp == 'nightly' && 'dev-main' || format('~{0}.0', matrix.wp)) }}" - mysqladmin -uroot -proot create wordpress_test - - - name: Run the tests - run: composer test:integration From dfed12245d5207b970510bebd8b1480b0190f2af Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Fri, 23 Jun 2023 23:48:09 +0200 Subject: [PATCH 208/270] Update the deployment config. --- .distignore | 22 ---------------------- .gitattributes | 29 +++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 22 deletions(-) delete mode 100644 .distignore create mode 100644 .gitattributes diff --git a/.distignore b/.distignore deleted file mode 100644 index d8c81aa..0000000 --- a/.distignore +++ /dev/null @@ -1,22 +0,0 @@ -# Directories -.git -.github -.wordpress-org -bin -node_modules -tests -vendor - -# Files -.editorconfig -.distignore -.gitignore -codeception.dist.yml -composer.json -composer.lock -CONTRIBUTING.md -package-lock.json -package.json -phpcs.xml.dist -phpstan.neon.dist -SECURITY.md diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..28fe199 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,29 @@ +* text=auto + +# Directories +/.git export-ignore +/.github export-ignore +/.wordpress-org export-ignore +/bin export-ignore +/node_modules export-ignore +/tests export-ignore +/vendor export-ignore + +# Files +/.gitattributes export-ignore +/.editorconfig export-ignore +/.gitignore export-ignore +/.npmrc export-ignore +/.nvmrc export-ignore +/assets/*.map export-ignore +/assets/*.scss export-ignore +/codeception.dist.yml export-ignore +/composer.lock export-ignore +/CONTRIBUTING.md export-ignore +/docker-compose.yml export-ignore +/package-lock.json export-ignore +/package.json export-ignore +/phpcs.xml.dist export-ignore +/phpstan.neon.dist export-ignore +/readme.md export-ignore +/SECURITY.md export-ignore From c6d2090b12326194c3f06f97fd35494e50250c0d Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 24 Jun 2023 00:04:04 +0200 Subject: [PATCH 209/270] Less ignorance. --- .gitignore | 12 +- package-lock.json | 3387 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 3389 insertions(+), 10 deletions(-) create mode 100644 package-lock.json diff --git a/.gitignore b/.gitignore index 86b3a97..30cde05 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,6 @@ -# Directories -/build +/composer.lock +/vendor /node_modules -/svn /tests/_output/ /tests/_support/_generated /tests/cache -/tests/wordpress -/vendor - -# Files -/composer.lock -/package-lock.json -/tests/.env diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..63c1599 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3387 @@ +{ + "name": "user-switching", + "version": "1.7.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "user-switching", + "version": "1.7.0", + "license": "GPL-2.0-or-later", + "devDependencies": { + "plugin-infrastructure": "file:vendor/johnbillion/plugin-infrastructure", + "version-bump-prompt": "^6.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@actions/github": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@actions/github/-/github-2.2.0.tgz", + "integrity": "sha512-9UAZqn8ywdR70n3GwVle4N8ALosQs4z50N7XMXrSTUVOmVpaBC5kE3TRTT7qQdi3OaQV24mjGuJZsHUmhD+ZXw==", + "dev": true, + "dependencies": { + "@actions/http-client": "^1.0.3", + "@octokit/graphql": "^4.3.1", + "@octokit/rest": "^16.43.1" + } + }, + "node_modules/@actions/http-client": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz", + "integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==", + "dev": true, + "dependencies": { + "tunnel": "0.0.6" + } + }, + "node_modules/@jsdevtools/ez-spawn": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@jsdevtools/ez-spawn/-/ez-spawn-3.0.4.tgz", + "integrity": "sha512-f5DRIOZf7wxogefH03RjMPMdBF7ADTWUMoOs9kaJo06EfwF+aFhMZMDZxHg/Xe12hptN9xoZjGso2fdjapBRIA==", + "dev": true, + "dependencies": { + "call-me-maybe": "^1.0.1", + "cross-spawn": "^7.0.3", + "string-argv": "^0.3.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jsdevtools/version-bump-prompt": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@jsdevtools/version-bump-prompt/-/version-bump-prompt-6.1.0.tgz", + "integrity": "sha512-NJFLJRiD3LLFBgSxAb6B255xhWCGgdtzmh6UjHK2b7SRGX2DDKJH5O4BJ0GTStBu4NnaNgMbkr1TLW3pLOBkOQ==", + "dev": true, + "dependencies": { + "@jsdevtools/ez-spawn": "^3.0.4", + "command-line-args": "^5.1.1", + "detect-indent": "^6.0.0", + "detect-newline": "^3.1.0", + "globby": "^11.0.1", + "inquirer": "^7.3.3", + "log-symbols": "^4.0.0", + "semver": "^7.3.2" + }, + "bin": { + "bump": "bin/bump.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@octokit/auth-token": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", + "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", + "dev": true, + "dependencies": { + "@octokit/types": "^6.0.3" + } + }, + "node_modules/@octokit/core": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz", + "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", + "dev": true, + "peer": true, + "dependencies": { + "@octokit/auth-token": "^3.0.0", + "@octokit/graphql": "^5.0.0", + "@octokit/request": "^6.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/core/node_modules/@octokit/auth-token": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz", + "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/core/node_modules/@octokit/endpoint": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz", + "integrity": "sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==", + "dev": true, + "peer": true, + "dependencies": { + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/core/node_modules/@octokit/graphql": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", + "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", + "dev": true, + "peer": true, + "dependencies": { + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/core/node_modules/@octokit/openapi-types": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.0.0.tgz", + "integrity": "sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw==", + "dev": true, + "peer": true + }, + "node_modules/@octokit/core/node_modules/@octokit/request": { + "version": "6.2.8", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz", + "integrity": "sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==", + "dev": true, + "peer": true, + "dependencies": { + "@octokit/endpoint": "^7.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/core/node_modules/@octokit/request-error": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz", + "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==", + "dev": true, + "peer": true, + "dependencies": { + "@octokit/types": "^9.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/core/node_modules/@octokit/types": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz", + "integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==", + "dev": true, + "peer": true, + "dependencies": { + "@octokit/openapi-types": "^18.0.0" + } + }, + "node_modules/@octokit/endpoint": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", + "dev": true, + "dependencies": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/graphql": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", + "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", + "dev": true, + "dependencies": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "12.11.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz", + "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==", + "dev": true + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-1.1.2.tgz", + "integrity": "sha512-jbsSoi5Q1pj63sC16XIUboklNw+8tL9VOnJsWycWYR78TKss5PVpIPb1TUUcMQ+bBh7cY579cVAWmf5qG+dw+Q==", + "dev": true, + "dependencies": { + "@octokit/types": "^2.0.1" + } + }, + "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", + "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", + "dev": true, + "dependencies": { + "@types/node": ">= 8" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "dev": true, + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-2.4.0.tgz", + "integrity": "sha512-EZi/AWhtkdfAYi01obpX0DF7U6b1VRr30QNQ5xSFPITMdLSfhcBqjamE3F+sKcxPbD7eZuMHu3Qkk2V+JGxBDQ==", + "dev": true, + "dependencies": { + "@octokit/types": "^2.0.1", + "deprecation": "^2.3.1" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", + "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", + "dev": true, + "dependencies": { + "@types/node": ">= 8" + } + }, + "node_modules/@octokit/request": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", + "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", + "dev": true, + "dependencies": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/request-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", + "dev": true, + "dependencies": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "node_modules/@octokit/rest": { + "version": "16.43.2", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.43.2.tgz", + "integrity": "sha512-ngDBevLbBTFfrHZeiS7SAMAZ6ssuVmXuya+F/7RaVvlysgGa1JKJkKWY+jV6TCJYcW0OALfJ7nTIGXcBXzycfQ==", + "dev": true, + "dependencies": { + "@octokit/auth-token": "^2.4.0", + "@octokit/plugin-paginate-rest": "^1.1.1", + "@octokit/plugin-request-log": "^1.0.0", + "@octokit/plugin-rest-endpoint-methods": "2.4.0", + "@octokit/request": "^5.2.0", + "@octokit/request-error": "^1.0.2", + "atob-lite": "^2.0.0", + "before-after-hook": "^2.0.0", + "btoa-lite": "^1.0.0", + "deprecation": "^2.0.0", + "lodash.get": "^4.4.2", + "lodash.set": "^4.3.2", + "lodash.uniq": "^4.5.0", + "octokit-pagination-methods": "^1.1.0", + "once": "^1.4.0", + "universal-user-agent": "^4.0.0" + } + }, + "node_modules/@octokit/rest/node_modules/@octokit/request-error": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-1.2.1.tgz", + "integrity": "sha512-+6yDyk1EES6WK+l3viRDElw96MvwfJxCt45GvmjDUKWjYIb3PJZQkq3i46TwGwoPD4h8NmTrENmtyA1FwbmhRA==", + "dev": true, + "dependencies": { + "@octokit/types": "^2.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "node_modules/@octokit/rest/node_modules/@octokit/types": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", + "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", + "dev": true, + "dependencies": { + "@types/node": ">= 8" + } + }, + "node_modules/@octokit/rest/node_modules/universal-user-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.1.tgz", + "integrity": "sha512-LnST3ebHwVL2aNe4mejI9IQh2HfZ1RLo8Io2HugSif8ekzD1TlWpHpColOB/eh8JHMLkGH3Akqf040I+4ylNxg==", + "dev": true, + "dependencies": { + "os-name": "^3.1.0" + } + }, + "node_modules/@octokit/types": { + "version": "6.41.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz", + "integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==", + "dev": true, + "dependencies": { + "@octokit/openapi-types": "^12.11.0" + } + }, + "node_modules/@types/node": { + "version": "20.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz", + "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==", + "dev": true + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/atob-lite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/atob-lite/-/atob-lite-2.0.0.tgz", + "integrity": "sha512-LEeSAWeh2Gfa2FtlQE1shxQ8zi5F9GHarrGKz08TMdODD5T4eH6BMsvtnhbWZ+XQn+Gb6om/917ucvRu7l7ukw==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/btoa-lite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", + "integrity": "sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA==", + "dev": true + }, + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", + "dev": true + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/command-line-args": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", + "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", + "dev": true, + "dependencies": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/execa/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/execa/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/execa/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dev": true, + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/inquirer": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", + "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.19", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.6.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, + "node_modules/lodash.set": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", + "integrity": "sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg==", + "dev": true + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/macos-release": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.1.tgz", + "integrity": "sha512-DXqXhEM7gW59OjZO8NIjBCz9AQ1BEMrfiOAl4AYByHCtVHRF4KoGNO8mqQeM8lRCtQe/UnJ4imO/d2HdkKsd+A==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/octokit-pagination-methods": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz", + "integrity": "sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ==", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-name": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", + "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", + "dev": true, + "dependencies": { + "macos-release": "^2.2.0", + "windows-release": "^3.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/plugin-infrastructure": { + "resolved": "vendor/johnbillion/plugin-infrastructure", + "link": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/replace-in-file": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/replace-in-file/-/replace-in-file-5.0.2.tgz", + "integrity": "sha512-1Vc7Sbr/rTuHgU1PZuBb7tGsFx3D4NKdhV4BpEF2MuN/6+SoXcFtx+dZ1Zz+5Dq4k5x9js87Y+gXQYPTQ9ppkA==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "glob": "^7.1.6", + "yargs": "^15.0.2" + }, + "bin": { + "replace-in-file": "bin/cli.js" + } + }, + "node_modules/replace-in-file/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/semver": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "dev": true, + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", + "dev": true + }, + "node_modules/version-bump-prompt": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/version-bump-prompt/-/version-bump-prompt-6.1.0.tgz", + "integrity": "sha512-GYC83GP8QOunWueKf2mbtZkdmisXhnBZPhIHWUmN/Yi4XXAQlIi9avM/IGWdI7KkJLfMENzGN1Xee+Zl3VJ5jg==", + "dev": true, + "dependencies": { + "@jsdevtools/version-bump-prompt": "6.1.0" + }, + "bin": { + "bump": "bump.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true + }, + "node_modules/windows-release": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.3.tgz", + "integrity": "sha512-OSOGH1QYiW5yVor9TtmXKQvt2vjQqbYS+DqmsZw+r7xDwLXEeT3JGW0ZppFmHx4diyXmxt238KFR3N9jzevBRg==", + "dev": true, + "dependencies": { + "execa": "^1.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "vendor/johnbillion/plugin-infrastructure": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@actions/github": "^2", + "replace-in-file": "^5", + "semver": "^7" + }, + "engines": { + "node": ">=16" + } + } + }, + "dependencies": { + "@actions/github": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@actions/github/-/github-2.2.0.tgz", + "integrity": "sha512-9UAZqn8ywdR70n3GwVle4N8ALosQs4z50N7XMXrSTUVOmVpaBC5kE3TRTT7qQdi3OaQV24mjGuJZsHUmhD+ZXw==", + "dev": true, + "requires": { + "@actions/http-client": "^1.0.3", + "@octokit/graphql": "^4.3.1", + "@octokit/rest": "^16.43.1" + } + }, + "@actions/http-client": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz", + "integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==", + "dev": true, + "requires": { + "tunnel": "0.0.6" + } + }, + "@jsdevtools/ez-spawn": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@jsdevtools/ez-spawn/-/ez-spawn-3.0.4.tgz", + "integrity": "sha512-f5DRIOZf7wxogefH03RjMPMdBF7ADTWUMoOs9kaJo06EfwF+aFhMZMDZxHg/Xe12hptN9xoZjGso2fdjapBRIA==", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "cross-spawn": "^7.0.3", + "string-argv": "^0.3.1", + "type-detect": "^4.0.8" + } + }, + "@jsdevtools/version-bump-prompt": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@jsdevtools/version-bump-prompt/-/version-bump-prompt-6.1.0.tgz", + "integrity": "sha512-NJFLJRiD3LLFBgSxAb6B255xhWCGgdtzmh6UjHK2b7SRGX2DDKJH5O4BJ0GTStBu4NnaNgMbkr1TLW3pLOBkOQ==", + "dev": true, + "requires": { + "@jsdevtools/ez-spawn": "^3.0.4", + "command-line-args": "^5.1.1", + "detect-indent": "^6.0.0", + "detect-newline": "^3.1.0", + "globby": "^11.0.1", + "inquirer": "^7.3.3", + "log-symbols": "^4.0.0", + "semver": "^7.3.2" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@octokit/auth-token": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", + "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", + "dev": true, + "requires": { + "@octokit/types": "^6.0.3" + } + }, + "@octokit/core": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz", + "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", + "dev": true, + "peer": true, + "requires": { + "@octokit/auth-token": "^3.0.0", + "@octokit/graphql": "^5.0.0", + "@octokit/request": "^6.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "dependencies": { + "@octokit/auth-token": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz", + "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==", + "dev": true, + "peer": true + }, + "@octokit/endpoint": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz", + "integrity": "sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==", + "dev": true, + "peer": true, + "requires": { + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/graphql": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", + "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", + "dev": true, + "peer": true, + "requires": { + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/openapi-types": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.0.0.tgz", + "integrity": "sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw==", + "dev": true, + "peer": true + }, + "@octokit/request": { + "version": "6.2.8", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz", + "integrity": "sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==", + "dev": true, + "peer": true, + "requires": { + "@octokit/endpoint": "^7.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request-error": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz", + "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==", + "dev": true, + "peer": true, + "requires": { + "@octokit/types": "^9.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/types": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz", + "integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==", + "dev": true, + "peer": true, + "requires": { + "@octokit/openapi-types": "^18.0.0" + } + } + } + }, + "@octokit/endpoint": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", + "dev": true, + "requires": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/graphql": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", + "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", + "dev": true, + "requires": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/openapi-types": { + "version": "12.11.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz", + "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==", + "dev": true + }, + "@octokit/plugin-paginate-rest": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-1.1.2.tgz", + "integrity": "sha512-jbsSoi5Q1pj63sC16XIUboklNw+8tL9VOnJsWycWYR78TKss5PVpIPb1TUUcMQ+bBh7cY579cVAWmf5qG+dw+Q==", + "dev": true, + "requires": { + "@octokit/types": "^2.0.1" + }, + "dependencies": { + "@octokit/types": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", + "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", + "dev": true, + "requires": { + "@types/node": ">= 8" + } + } + } + }, + "@octokit/plugin-request-log": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "dev": true, + "requires": {} + }, + "@octokit/plugin-rest-endpoint-methods": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-2.4.0.tgz", + "integrity": "sha512-EZi/AWhtkdfAYi01obpX0DF7U6b1VRr30QNQ5xSFPITMdLSfhcBqjamE3F+sKcxPbD7eZuMHu3Qkk2V+JGxBDQ==", + "dev": true, + "requires": { + "@octokit/types": "^2.0.1", + "deprecation": "^2.3.1" + }, + "dependencies": { + "@octokit/types": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", + "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", + "dev": true, + "requires": { + "@types/node": ">= 8" + } + } + } + }, + "@octokit/request": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", + "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", + "dev": true, + "requires": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", + "dev": true, + "requires": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/rest": { + "version": "16.43.2", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.43.2.tgz", + "integrity": "sha512-ngDBevLbBTFfrHZeiS7SAMAZ6ssuVmXuya+F/7RaVvlysgGa1JKJkKWY+jV6TCJYcW0OALfJ7nTIGXcBXzycfQ==", + "dev": true, + "requires": { + "@octokit/auth-token": "^2.4.0", + "@octokit/plugin-paginate-rest": "^1.1.1", + "@octokit/plugin-request-log": "^1.0.0", + "@octokit/plugin-rest-endpoint-methods": "2.4.0", + "@octokit/request": "^5.2.0", + "@octokit/request-error": "^1.0.2", + "atob-lite": "^2.0.0", + "before-after-hook": "^2.0.0", + "btoa-lite": "^1.0.0", + "deprecation": "^2.0.0", + "lodash.get": "^4.4.2", + "lodash.set": "^4.3.2", + "lodash.uniq": "^4.5.0", + "octokit-pagination-methods": "^1.1.0", + "once": "^1.4.0", + "universal-user-agent": "^4.0.0" + }, + "dependencies": { + "@octokit/request-error": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-1.2.1.tgz", + "integrity": "sha512-+6yDyk1EES6WK+l3viRDElw96MvwfJxCt45GvmjDUKWjYIb3PJZQkq3i46TwGwoPD4h8NmTrENmtyA1FwbmhRA==", + "dev": true, + "requires": { + "@octokit/types": "^2.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/types": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", + "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", + "dev": true, + "requires": { + "@types/node": ">= 8" + } + }, + "universal-user-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.1.tgz", + "integrity": "sha512-LnST3ebHwVL2aNe4mejI9IQh2HfZ1RLo8Io2HugSif8ekzD1TlWpHpColOB/eh8JHMLkGH3Akqf040I+4ylNxg==", + "dev": true, + "requires": { + "os-name": "^3.1.0" + } + } + } + }, + "@octokit/types": { + "version": "6.41.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz", + "integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==", + "dev": true, + "requires": { + "@octokit/openapi-types": "^12.11.0" + } + }, + "@types/node": { + "version": "20.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz", + "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "atob-lite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/atob-lite/-/atob-lite-2.0.0.tgz", + "integrity": "sha512-LEeSAWeh2Gfa2FtlQE1shxQ8zi5F9GHarrGKz08TMdODD5T4eH6BMsvtnhbWZ+XQn+Gb6om/917ucvRu7l7ukw==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "btoa-lite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", + "integrity": "sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA==", + "dev": true + }, + "call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "command-line-args": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", + "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", + "dev": true, + "requires": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true + }, + "deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true + }, + "detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dev": true, + "requires": { + "array-back": "^3.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "inquirer": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", + "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.19", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.6.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, + "lodash.set": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", + "integrity": "sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg==", + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "macos-release": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.1.tgz", + "integrity": "sha512-DXqXhEM7gW59OjZO8NIjBCz9AQ1BEMrfiOAl4AYByHCtVHRF4KoGNO8mqQeM8lRCtQe/UnJ4imO/d2HdkKsd+A==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "dev": true, + "requires": { + "path-key": "^2.0.0" + }, + "dependencies": { + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true + } + } + }, + "octokit-pagination-methods": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz", + "integrity": "sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "os-name": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", + "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", + "dev": true, + "requires": { + "macos-release": "^2.2.0", + "windows-release": "^3.1.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "plugin-infrastructure": { + "version": "file:vendor/johnbillion/plugin-infrastructure", + "requires": { + "@actions/github": "^2", + "replace-in-file": "^5", + "semver": "^7" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "replace-in-file": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/replace-in-file/-/replace-in-file-5.0.2.tgz", + "integrity": "sha512-1Vc7Sbr/rTuHgU1PZuBb7tGsFx3D4NKdhV4BpEF2MuN/6+SoXcFtx+dZ1Zz+5Dq4k5x9js87Y+gXQYPTQ9ppkA==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "glob": "^7.1.6", + "yargs": "^15.0.2" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "dev": true + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + }, + "typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "dev": true + }, + "universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", + "dev": true + }, + "version-bump-prompt": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/version-bump-prompt/-/version-bump-prompt-6.1.0.tgz", + "integrity": "sha512-GYC83GP8QOunWueKf2mbtZkdmisXhnBZPhIHWUmN/Yi4XXAQlIi9avM/IGWdI7KkJLfMENzGN1Xee+Zl3VJ5jg==", + "dev": true, + "requires": { + "@jsdevtools/version-bump-prompt": "6.1.0" + } + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true + }, + "windows-release": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.3.tgz", + "integrity": "sha512-OSOGH1QYiW5yVor9TtmXKQvt2vjQqbYS+DqmsZw+r7xDwLXEeT3JGW0ZppFmHx4diyXmxt238KFR3N9jzevBRg==", + "dev": true, + "requires": { + "execa": "^1.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} From d5984eb782785bff265b75e5c424cc42a1979961 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 24 Jun 2023 00:07:38 +0200 Subject: [PATCH 210/270] Can't run the coding standards tests on PHP 5.6. --- .github/workflows/coding-standards.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index d7f851e..c3c965b 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -21,7 +21,6 @@ jobs: php: - '8.2' - '7.4' - - '5.6' fail-fast: false with: php: ${{ matrix.php }} From aaf091b86a56774f18192b254eaad2cf7f42b848 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 24 Jun 2023 00:15:43 +0200 Subject: [PATCH 211/270] Don't run Node steps during integration tests. --- .github/workflows/integration-tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 6d502d5..5c2ef2d 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -33,3 +33,4 @@ jobs: with: wp: ${{ matrix.wp }} php: ${{ matrix.php }} + node: false From 6f4f22503ae4ca9e6fceaec07d29d5f1d354e599 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 24 Jun 2023 00:17:08 +0200 Subject: [PATCH 212/270] Don't need this in the repo now. --- .gitignore | 1 + package-lock.json | 3387 --------------------------------------------- 2 files changed, 1 insertion(+), 3387 deletions(-) delete mode 100644 package-lock.json diff --git a/.gitignore b/.gitignore index 30cde05..136ba2b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /composer.lock +/package-lock.json /vendor /node_modules /tests/_output/ diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 63c1599..0000000 --- a/package-lock.json +++ /dev/null @@ -1,3387 +0,0 @@ -{ - "name": "user-switching", - "version": "1.7.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "user-switching", - "version": "1.7.0", - "license": "GPL-2.0-or-later", - "devDependencies": { - "plugin-infrastructure": "file:vendor/johnbillion/plugin-infrastructure", - "version-bump-prompt": "^6.1.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@actions/github": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@actions/github/-/github-2.2.0.tgz", - "integrity": "sha512-9UAZqn8ywdR70n3GwVle4N8ALosQs4z50N7XMXrSTUVOmVpaBC5kE3TRTT7qQdi3OaQV24mjGuJZsHUmhD+ZXw==", - "dev": true, - "dependencies": { - "@actions/http-client": "^1.0.3", - "@octokit/graphql": "^4.3.1", - "@octokit/rest": "^16.43.1" - } - }, - "node_modules/@actions/http-client": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz", - "integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==", - "dev": true, - "dependencies": { - "tunnel": "0.0.6" - } - }, - "node_modules/@jsdevtools/ez-spawn": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@jsdevtools/ez-spawn/-/ez-spawn-3.0.4.tgz", - "integrity": "sha512-f5DRIOZf7wxogefH03RjMPMdBF7ADTWUMoOs9kaJo06EfwF+aFhMZMDZxHg/Xe12hptN9xoZjGso2fdjapBRIA==", - "dev": true, - "dependencies": { - "call-me-maybe": "^1.0.1", - "cross-spawn": "^7.0.3", - "string-argv": "^0.3.1", - "type-detect": "^4.0.8" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@jsdevtools/version-bump-prompt": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@jsdevtools/version-bump-prompt/-/version-bump-prompt-6.1.0.tgz", - "integrity": "sha512-NJFLJRiD3LLFBgSxAb6B255xhWCGgdtzmh6UjHK2b7SRGX2DDKJH5O4BJ0GTStBu4NnaNgMbkr1TLW3pLOBkOQ==", - "dev": true, - "dependencies": { - "@jsdevtools/ez-spawn": "^3.0.4", - "command-line-args": "^5.1.1", - "detect-indent": "^6.0.0", - "detect-newline": "^3.1.0", - "globby": "^11.0.1", - "inquirer": "^7.3.3", - "log-symbols": "^4.0.0", - "semver": "^7.3.2" - }, - "bin": { - "bump": "bin/bump.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@octokit/auth-token": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", - "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", - "dev": true, - "dependencies": { - "@octokit/types": "^6.0.3" - } - }, - "node_modules/@octokit/core": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz", - "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", - "dev": true, - "peer": true, - "dependencies": { - "@octokit/auth-token": "^3.0.0", - "@octokit/graphql": "^5.0.0", - "@octokit/request": "^6.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^9.0.0", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/core/node_modules/@octokit/auth-token": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz", - "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/core/node_modules/@octokit/endpoint": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz", - "integrity": "sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==", - "dev": true, - "peer": true, - "dependencies": { - "@octokit/types": "^9.0.0", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/core/node_modules/@octokit/graphql": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", - "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", - "dev": true, - "peer": true, - "dependencies": { - "@octokit/request": "^6.0.0", - "@octokit/types": "^9.0.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/core/node_modules/@octokit/openapi-types": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.0.0.tgz", - "integrity": "sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw==", - "dev": true, - "peer": true - }, - "node_modules/@octokit/core/node_modules/@octokit/request": { - "version": "6.2.8", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz", - "integrity": "sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==", - "dev": true, - "peer": true, - "dependencies": { - "@octokit/endpoint": "^7.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^9.0.0", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/core/node_modules/@octokit/request-error": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz", - "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==", - "dev": true, - "peer": true, - "dependencies": { - "@octokit/types": "^9.0.0", - "deprecation": "^2.0.0", - "once": "^1.4.0" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/core/node_modules/@octokit/types": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz", - "integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==", - "dev": true, - "peer": true, - "dependencies": { - "@octokit/openapi-types": "^18.0.0" - } - }, - "node_modules/@octokit/endpoint": { - "version": "6.0.12", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", - "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", - "dev": true, - "dependencies": { - "@octokit/types": "^6.0.3", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/graphql": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", - "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", - "dev": true, - "dependencies": { - "@octokit/request": "^5.6.0", - "@octokit/types": "^6.0.3", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/openapi-types": { - "version": "12.11.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz", - "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==", - "dev": true - }, - "node_modules/@octokit/plugin-paginate-rest": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-1.1.2.tgz", - "integrity": "sha512-jbsSoi5Q1pj63sC16XIUboklNw+8tL9VOnJsWycWYR78TKss5PVpIPb1TUUcMQ+bBh7cY579cVAWmf5qG+dw+Q==", - "dev": true, - "dependencies": { - "@octokit/types": "^2.0.1" - } - }, - "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": { - "version": "2.16.2", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", - "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", - "dev": true, - "dependencies": { - "@types/node": ">= 8" - } - }, - "node_modules/@octokit/plugin-request-log": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", - "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", - "dev": true, - "peerDependencies": { - "@octokit/core": ">=3" - } - }, - "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-2.4.0.tgz", - "integrity": "sha512-EZi/AWhtkdfAYi01obpX0DF7U6b1VRr30QNQ5xSFPITMdLSfhcBqjamE3F+sKcxPbD7eZuMHu3Qkk2V+JGxBDQ==", - "dev": true, - "dependencies": { - "@octokit/types": "^2.0.1", - "deprecation": "^2.3.1" - } - }, - "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": { - "version": "2.16.2", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", - "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", - "dev": true, - "dependencies": { - "@types/node": ">= 8" - } - }, - "node_modules/@octokit/request": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", - "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", - "dev": true, - "dependencies": { - "@octokit/endpoint": "^6.0.1", - "@octokit/request-error": "^2.1.0", - "@octokit/types": "^6.16.1", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/request-error": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", - "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", - "dev": true, - "dependencies": { - "@octokit/types": "^6.0.3", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "node_modules/@octokit/rest": { - "version": "16.43.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.43.2.tgz", - "integrity": "sha512-ngDBevLbBTFfrHZeiS7SAMAZ6ssuVmXuya+F/7RaVvlysgGa1JKJkKWY+jV6TCJYcW0OALfJ7nTIGXcBXzycfQ==", - "dev": true, - "dependencies": { - "@octokit/auth-token": "^2.4.0", - "@octokit/plugin-paginate-rest": "^1.1.1", - "@octokit/plugin-request-log": "^1.0.0", - "@octokit/plugin-rest-endpoint-methods": "2.4.0", - "@octokit/request": "^5.2.0", - "@octokit/request-error": "^1.0.2", - "atob-lite": "^2.0.0", - "before-after-hook": "^2.0.0", - "btoa-lite": "^1.0.0", - "deprecation": "^2.0.0", - "lodash.get": "^4.4.2", - "lodash.set": "^4.3.2", - "lodash.uniq": "^4.5.0", - "octokit-pagination-methods": "^1.1.0", - "once": "^1.4.0", - "universal-user-agent": "^4.0.0" - } - }, - "node_modules/@octokit/rest/node_modules/@octokit/request-error": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-1.2.1.tgz", - "integrity": "sha512-+6yDyk1EES6WK+l3viRDElw96MvwfJxCt45GvmjDUKWjYIb3PJZQkq3i46TwGwoPD4h8NmTrENmtyA1FwbmhRA==", - "dev": true, - "dependencies": { - "@octokit/types": "^2.0.0", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "node_modules/@octokit/rest/node_modules/@octokit/types": { - "version": "2.16.2", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", - "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", - "dev": true, - "dependencies": { - "@types/node": ">= 8" - } - }, - "node_modules/@octokit/rest/node_modules/universal-user-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.1.tgz", - "integrity": "sha512-LnST3ebHwVL2aNe4mejI9IQh2HfZ1RLo8Io2HugSif8ekzD1TlWpHpColOB/eh8JHMLkGH3Akqf040I+4ylNxg==", - "dev": true, - "dependencies": { - "os-name": "^3.1.0" - } - }, - "node_modules/@octokit/types": { - "version": "6.41.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz", - "integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==", - "dev": true, - "dependencies": { - "@octokit/openapi-types": "^12.11.0" - } - }, - "node_modules/@types/node": { - "version": "20.3.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz", - "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==", - "dev": true - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/array-back": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", - "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/atob-lite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/atob-lite/-/atob-lite-2.0.0.tgz", - "integrity": "sha512-LEeSAWeh2Gfa2FtlQE1shxQ8zi5F9GHarrGKz08TMdODD5T4eH6BMsvtnhbWZ+XQn+Gb6om/917ucvRu7l7ukw==", - "dev": true - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/before-after-hook": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA==", - "dev": true - }, - "node_modules/call-me-maybe": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", - "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", - "dev": true - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/command-line-args": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", - "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", - "dev": true, - "dependencies": { - "array-back": "^3.1.0", - "find-replace": "^3.0.0", - "lodash.camelcase": "^4.3.0", - "typical": "^4.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "dev": true - }, - "node_modules/detect-indent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/execa/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/execa/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/execa/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/execa/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/execa/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/execa/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-replace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", - "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", - "dev": true, - "dependencies": { - "array-back": "^3.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/inquirer": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", - "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.19", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.6.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "dev": true - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true - }, - "node_modules/lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg==", - "dev": true - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "dev": true - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/macos-release": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.1.tgz", - "integrity": "sha512-DXqXhEM7gW59OjZO8NIjBCz9AQ1BEMrfiOAl4AYByHCtVHRF4KoGNO8mqQeM8lRCtQe/UnJ4imO/d2HdkKsd+A==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node_modules/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", - "dev": true, - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/octokit-pagination-methods": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz", - "integrity": "sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ==", - "dev": true - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "dev": true, - "dependencies": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/plugin-infrastructure": { - "resolved": "vendor/johnbillion/plugin-infrastructure", - "link": true - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/replace-in-file": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/replace-in-file/-/replace-in-file-5.0.2.tgz", - "integrity": "sha512-1Vc7Sbr/rTuHgU1PZuBb7tGsFx3D4NKdhV4BpEF2MuN/6+SoXcFtx+dZ1Zz+5Dq4k5x9js87Y+gXQYPTQ9ppkA==", - "dev": true, - "dependencies": { - "chalk": "^3.0.0", - "glob": "^7.1.6", - "yargs": "^15.0.2" - }, - "bin": { - "replace-in-file": "bin/cli.js" - } - }, - "node_modules/replace-in-file/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-argv": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", - "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", - "dev": true, - "engines": { - "node": ">=0.6.19" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", - "dev": true, - "engines": { - "node": ">=0.6.11 <=0.7.0 || >=0.7.3" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typical": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", - "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/universal-user-agent": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", - "dev": true - }, - "node_modules/version-bump-prompt": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/version-bump-prompt/-/version-bump-prompt-6.1.0.tgz", - "integrity": "sha512-GYC83GP8QOunWueKf2mbtZkdmisXhnBZPhIHWUmN/Yi4XXAQlIi9avM/IGWdI7KkJLfMENzGN1Xee+Zl3VJ5jg==", - "dev": true, - "dependencies": { - "@jsdevtools/version-bump-prompt": "6.1.0" - }, - "bin": { - "bump": "bump.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true - }, - "node_modules/windows-release": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.3.tgz", - "integrity": "sha512-OSOGH1QYiW5yVor9TtmXKQvt2vjQqbYS+DqmsZw+r7xDwLXEeT3JGW0ZppFmHx4diyXmxt238KFR3N9jzevBRg==", - "dev": true, - "dependencies": { - "execa": "^1.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "vendor/johnbillion/plugin-infrastructure": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@actions/github": "^2", - "replace-in-file": "^5", - "semver": "^7" - }, - "engines": { - "node": ">=16" - } - } - }, - "dependencies": { - "@actions/github": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@actions/github/-/github-2.2.0.tgz", - "integrity": "sha512-9UAZqn8ywdR70n3GwVle4N8ALosQs4z50N7XMXrSTUVOmVpaBC5kE3TRTT7qQdi3OaQV24mjGuJZsHUmhD+ZXw==", - "dev": true, - "requires": { - "@actions/http-client": "^1.0.3", - "@octokit/graphql": "^4.3.1", - "@octokit/rest": "^16.43.1" - } - }, - "@actions/http-client": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz", - "integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==", - "dev": true, - "requires": { - "tunnel": "0.0.6" - } - }, - "@jsdevtools/ez-spawn": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@jsdevtools/ez-spawn/-/ez-spawn-3.0.4.tgz", - "integrity": "sha512-f5DRIOZf7wxogefH03RjMPMdBF7ADTWUMoOs9kaJo06EfwF+aFhMZMDZxHg/Xe12hptN9xoZjGso2fdjapBRIA==", - "dev": true, - "requires": { - "call-me-maybe": "^1.0.1", - "cross-spawn": "^7.0.3", - "string-argv": "^0.3.1", - "type-detect": "^4.0.8" - } - }, - "@jsdevtools/version-bump-prompt": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@jsdevtools/version-bump-prompt/-/version-bump-prompt-6.1.0.tgz", - "integrity": "sha512-NJFLJRiD3LLFBgSxAb6B255xhWCGgdtzmh6UjHK2b7SRGX2DDKJH5O4BJ0GTStBu4NnaNgMbkr1TLW3pLOBkOQ==", - "dev": true, - "requires": { - "@jsdevtools/ez-spawn": "^3.0.4", - "command-line-args": "^5.1.1", - "detect-indent": "^6.0.0", - "detect-newline": "^3.1.0", - "globby": "^11.0.1", - "inquirer": "^7.3.3", - "log-symbols": "^4.0.0", - "semver": "^7.3.2" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@octokit/auth-token": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", - "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", - "dev": true, - "requires": { - "@octokit/types": "^6.0.3" - } - }, - "@octokit/core": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz", - "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", - "dev": true, - "peer": true, - "requires": { - "@octokit/auth-token": "^3.0.0", - "@octokit/graphql": "^5.0.0", - "@octokit/request": "^6.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^9.0.0", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - }, - "dependencies": { - "@octokit/auth-token": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz", - "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==", - "dev": true, - "peer": true - }, - "@octokit/endpoint": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz", - "integrity": "sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==", - "dev": true, - "peer": true, - "requires": { - "@octokit/types": "^9.0.0", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/graphql": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", - "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", - "dev": true, - "peer": true, - "requires": { - "@octokit/request": "^6.0.0", - "@octokit/types": "^9.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/openapi-types": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.0.0.tgz", - "integrity": "sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw==", - "dev": true, - "peer": true - }, - "@octokit/request": { - "version": "6.2.8", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz", - "integrity": "sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==", - "dev": true, - "peer": true, - "requires": { - "@octokit/endpoint": "^7.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^9.0.0", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/request-error": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz", - "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==", - "dev": true, - "peer": true, - "requires": { - "@octokit/types": "^9.0.0", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "@octokit/types": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz", - "integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==", - "dev": true, - "peer": true, - "requires": { - "@octokit/openapi-types": "^18.0.0" - } - } - } - }, - "@octokit/endpoint": { - "version": "6.0.12", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", - "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", - "dev": true, - "requires": { - "@octokit/types": "^6.0.3", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/graphql": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", - "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", - "dev": true, - "requires": { - "@octokit/request": "^5.6.0", - "@octokit/types": "^6.0.3", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/openapi-types": { - "version": "12.11.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz", - "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==", - "dev": true - }, - "@octokit/plugin-paginate-rest": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-1.1.2.tgz", - "integrity": "sha512-jbsSoi5Q1pj63sC16XIUboklNw+8tL9VOnJsWycWYR78TKss5PVpIPb1TUUcMQ+bBh7cY579cVAWmf5qG+dw+Q==", - "dev": true, - "requires": { - "@octokit/types": "^2.0.1" - }, - "dependencies": { - "@octokit/types": { - "version": "2.16.2", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", - "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", - "dev": true, - "requires": { - "@types/node": ">= 8" - } - } - } - }, - "@octokit/plugin-request-log": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", - "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", - "dev": true, - "requires": {} - }, - "@octokit/plugin-rest-endpoint-methods": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-2.4.0.tgz", - "integrity": "sha512-EZi/AWhtkdfAYi01obpX0DF7U6b1VRr30QNQ5xSFPITMdLSfhcBqjamE3F+sKcxPbD7eZuMHu3Qkk2V+JGxBDQ==", - "dev": true, - "requires": { - "@octokit/types": "^2.0.1", - "deprecation": "^2.3.1" - }, - "dependencies": { - "@octokit/types": { - "version": "2.16.2", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", - "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", - "dev": true, - "requires": { - "@types/node": ">= 8" - } - } - } - }, - "@octokit/request": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", - "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", - "dev": true, - "requires": { - "@octokit/endpoint": "^6.0.1", - "@octokit/request-error": "^2.1.0", - "@octokit/types": "^6.16.1", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/request-error": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", - "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", - "dev": true, - "requires": { - "@octokit/types": "^6.0.3", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "@octokit/rest": { - "version": "16.43.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.43.2.tgz", - "integrity": "sha512-ngDBevLbBTFfrHZeiS7SAMAZ6ssuVmXuya+F/7RaVvlysgGa1JKJkKWY+jV6TCJYcW0OALfJ7nTIGXcBXzycfQ==", - "dev": true, - "requires": { - "@octokit/auth-token": "^2.4.0", - "@octokit/plugin-paginate-rest": "^1.1.1", - "@octokit/plugin-request-log": "^1.0.0", - "@octokit/plugin-rest-endpoint-methods": "2.4.0", - "@octokit/request": "^5.2.0", - "@octokit/request-error": "^1.0.2", - "atob-lite": "^2.0.0", - "before-after-hook": "^2.0.0", - "btoa-lite": "^1.0.0", - "deprecation": "^2.0.0", - "lodash.get": "^4.4.2", - "lodash.set": "^4.3.2", - "lodash.uniq": "^4.5.0", - "octokit-pagination-methods": "^1.1.0", - "once": "^1.4.0", - "universal-user-agent": "^4.0.0" - }, - "dependencies": { - "@octokit/request-error": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-1.2.1.tgz", - "integrity": "sha512-+6yDyk1EES6WK+l3viRDElw96MvwfJxCt45GvmjDUKWjYIb3PJZQkq3i46TwGwoPD4h8NmTrENmtyA1FwbmhRA==", - "dev": true, - "requires": { - "@octokit/types": "^2.0.0", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "@octokit/types": { - "version": "2.16.2", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", - "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", - "dev": true, - "requires": { - "@types/node": ">= 8" - } - }, - "universal-user-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.1.tgz", - "integrity": "sha512-LnST3ebHwVL2aNe4mejI9IQh2HfZ1RLo8Io2HugSif8ekzD1TlWpHpColOB/eh8JHMLkGH3Akqf040I+4ylNxg==", - "dev": true, - "requires": { - "os-name": "^3.1.0" - } - } - } - }, - "@octokit/types": { - "version": "6.41.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz", - "integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==", - "dev": true, - "requires": { - "@octokit/openapi-types": "^12.11.0" - } - }, - "@types/node": { - "version": "20.3.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz", - "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==", - "dev": true - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "array-back": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", - "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", - "dev": true - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "atob-lite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/atob-lite/-/atob-lite-2.0.0.tgz", - "integrity": "sha512-LEeSAWeh2Gfa2FtlQE1shxQ8zi5F9GHarrGKz08TMdODD5T4eH6BMsvtnhbWZ+XQn+Gb6om/917ucvRu7l7ukw==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "before-after-hook": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA==", - "dev": true - }, - "call-me-maybe": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", - "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true - }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "command-line-args": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", - "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", - "dev": true, - "requires": { - "array-back": "^3.1.0", - "find-replace": "^3.0.0", - "lodash.camelcase": "^4.3.0", - "typical": "^4.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true - }, - "deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "dev": true - }, - "detect-indent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true - }, - "detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-replace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", - "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", - "dev": true, - "requires": { - "array-back": "^3.0.1" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "inquirer": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", - "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.19", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.6.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "dev": true - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg==", - "dev": true - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "dev": true - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "macos-release": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.1.tgz", - "integrity": "sha512-DXqXhEM7gW59OjZO8NIjBCz9AQ1BEMrfiOAl4AYByHCtVHRF4KoGNO8mqQeM8lRCtQe/UnJ4imO/d2HdkKsd+A==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", - "dev": true, - "requires": { - "path-key": "^2.0.0" - }, - "dependencies": { - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true - } - } - }, - "octokit-pagination-methods": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz", - "integrity": "sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "dev": true, - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "plugin-infrastructure": { - "version": "file:vendor/johnbillion/plugin-infrastructure", - "requires": { - "@actions/github": "^2", - "replace-in-file": "^5", - "semver": "^7" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "replace-in-file": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/replace-in-file/-/replace-in-file-5.0.2.tgz", - "integrity": "sha512-1Vc7Sbr/rTuHgU1PZuBb7tGsFx3D4NKdhV4BpEF2MuN/6+SoXcFtx+dZ1Zz+5Dq4k5x9js87Y+gXQYPTQ9ppkA==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "glob": "^7.1.6", - "yargs": "^15.0.2" - }, - "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "string-argv": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", - "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", - "dev": true - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - }, - "typical": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", - "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", - "dev": true - }, - "universal-user-agent": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", - "dev": true - }, - "version-bump-prompt": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/version-bump-prompt/-/version-bump-prompt-6.1.0.tgz", - "integrity": "sha512-GYC83GP8QOunWueKf2mbtZkdmisXhnBZPhIHWUmN/Yi4XXAQlIi9avM/IGWdI7KkJLfMENzGN1Xee+Zl3VJ5jg==", - "dev": true, - "requires": { - "@jsdevtools/version-bump-prompt": "6.1.0" - } - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true - }, - "windows-release": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.3.tgz", - "integrity": "sha512-OSOGH1QYiW5yVor9TtmXKQvt2vjQqbYS+DqmsZw+r7xDwLXEeT3JGW0ZppFmHx4diyXmxt238KFR3N9jzevBRg==", - "dev": true, - "requires": { - "execa": "^1.0.0" - } - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } -} From 39782c481cbf9b4f3e086d281dfe57566db04d1a Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 2 Aug 2023 20:16:44 +0100 Subject: [PATCH 213/270] Switch to docker compose v2. --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index a8265e2..c032604 100644 --- a/composer.json +++ b/composer.json @@ -75,7 +75,7 @@ "acceptance-tests" ], "test:destroy": [ - "COMPOSE_PROJECT_NAME=user-switching docker-compose down --volumes --remove-orphans" + "COMPOSE_PROJECT_NAME=user-switching docker compose down --volumes --remove-orphans" ], "test:integration": [ "integration-tests" @@ -88,10 +88,10 @@ "phpstan analyze --memory-limit=1024M" ], "test:start": [ - "COMPOSE_PROJECT_NAME=user-switching docker-compose up -d" + "COMPOSE_PROJECT_NAME=user-switching docker compose up -d" ], "test:stop": [ - "COMPOSE_PROJECT_NAME=user-switching docker-compose down" + "COMPOSE_PROJECT_NAME=user-switching docker compose down" ] } } From 4885ed1ee62d6dcd40c094cc3db5d07b5b7d56fd Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 2 Aug 2023 20:18:25 +0100 Subject: [PATCH 214/270] Update the CI config. --- .github/workflows/acceptance-tests.yml | 21 ++++++++++++++++++--- .github/workflows/coding-standards.yml | 12 ++++++++++++ .github/workflows/integration-tests.yml | 19 ++++++++++++++++--- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml index fa46fbf..5ac386c 100644 --- a/.github/workflows/acceptance-tests.yml +++ b/.github/workflows/acceptance-tests.yml @@ -10,9 +10,18 @@ on: pull_request: branches: - '**' - # Once weekly on Thursdays at 08:00 UTC. schedule: - - cron: '0 8 * * 4' + # Once weekly on Mondays at 04:00 UTC. + # + # ┌───────────── minute (0 - 59) + # │ ┌────────── hour (0 - 23) + # │ │ ┌─────── day of the month (1 - 31) + # │ │ │ ┌──── month (1 - 12 or JAN-DEC) + # │ │ │ │ ┌─ day of the week (0 - 6 or SUN-SAT) + # │ │ │ │ │ + # │ │ │ │ │ + # │ │ │ │ │ + - cron: '0 4 * * 1' workflow_dispatch: jobs: @@ -21,12 +30,18 @@ jobs: strategy: matrix: wp: - - 'nightly' + - 'dev-nightly' - '6.2' php: - '8.2' - '7.4' - '5.6' + dev: + - ${{ github.ref_name == 'develop' }} + exclude: + # Only run the dev-nightly tests on the develop branch. + - wp: 'dev-nightly' + dev: false fail-fast: false uses: johnbillion/plugin-infrastructure/.github/workflows/reusable-acceptance-tests.yml@trunk with: diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index c3c965b..26ecab9 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -10,6 +10,18 @@ on: pull_request: branches: - '**' + schedule: + # Once weekly on Mondays at 03:00 UTC. + # + # ┌───────────── minute (0 - 59) + # │ ┌────────── hour (0 - 23) + # │ │ ┌─────── day of the month (1 - 31) + # │ │ │ ┌──── month (1 - 12 or JAN-DEC) + # │ │ │ │ ┌─ day of the week (0 - 6 or SUN-SAT) + # │ │ │ │ │ + # │ │ │ │ │ + # │ │ │ │ │ + - cron: '0 3 * * 1' workflow_dispatch: jobs: diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 5c2ef2d..2611407 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -10,6 +10,18 @@ on: pull_request: branches: - '**' + schedule: + # Once weekly on Mondays at 05:00 UTC. + # + # ┌───────────── minute (0 - 59) + # │ ┌────────── hour (0 - 23) + # │ │ ┌─────── day of the month (1 - 31) + # │ │ │ ┌──── month (1 - 12 or JAN-DEC) + # │ │ │ │ ┌─ day of the week (0 - 6 or SUN-SAT) + # │ │ │ │ │ + # │ │ │ │ │ + # │ │ │ │ │ + - cron: '0 5 * * 1' workflow_dispatch: jobs: @@ -18,15 +30,16 @@ jobs: uses: johnbillion/plugin-infrastructure/.github/workflows/reusable-integration-tests.yml@trunk strategy: matrix: - php: - - '8.2' - - '7.4' wp: - '*' - 'dev-nightly' + php: + - '8.2' + - '7.4' dev: - ${{ github.ref_name == 'develop' }} exclude: + # Only run the dev-nightly tests on the develop branch. - wp: 'dev-nightly' dev: false fail-fast: false From 61989534992c69c1774623940ba7647520dd5ce2 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 2 Aug 2023 20:18:34 +0100 Subject: [PATCH 215/270] Update some packages. --- composer.json | 6 +++--- tests/integration.suite.yml | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index c032604..4aef774 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ "homepage": "https://johnblackbourn.com/" } ], - "homepage": "https://github.com/johnbillion/user-switching", + "homepage": "https://github.com/johnbillion/user-switching/", "support": { "issues": "https://github.com/johnbillion/user-switching/issues", "forum": "https://wordpress.org/support/plugin/user-switching", @@ -23,7 +23,7 @@ ], "require": { "php": ">=5.3", - "composer/installers": "^1 || ^2" + "composer/installers": "^1.0 || ^2.0" }, "require-dev": { "codeception/module-asserts": "^1.0", @@ -39,7 +39,7 @@ "phpstan/phpstan-phpunit": "^1.0", "roots/wordpress": "*", "squizlabs/php_codesniffer": "3.7.1", - "szepeviktor/phpstan-wordpress": "1.1.6", + "szepeviktor/phpstan-wordpress": "1.3.0", "wp-coding-standards/wpcs": "2.3.0" }, "autoload-dev": { diff --git a/tests/integration.suite.yml b/tests/integration.suite.yml index 7abe0bb..4e751fb 100644 --- a/tests/integration.suite.yml +++ b/tests/integration.suite.yml @@ -16,6 +16,7 @@ modules: tablePrefix: wp_integration_ plugins: ['%COMPOSE_PROJECT_NAME%/%COMPOSE_PROJECT_NAME%.php'] activatePlugins: ['%COMPOSE_PROJECT_NAME%/%COMPOSE_PROJECT_NAME%.php'] + skipPluggables: true env: singlesite: modules: From bae2e24e7de8e40d3a71c34e959d929fa9b1ed49 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 2 Aug 2023 21:45:04 +0100 Subject: [PATCH 216/270] Switch to wordpress-full so we can test things on the front end too. --- composer.json | 5 +++-- docker-compose.yml | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 4aef774..fae7f32 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,8 @@ "phpcompatibility/phpcompatibility-wp": "2.1.4", "phpstan/phpstan": "^1.0", "phpstan/phpstan-phpunit": "^1.0", - "roots/wordpress": "*", + "roots/wordpress-core-installer": "^1.0.0", + "roots/wordpress-full": "*", "squizlabs/php_codesniffer": "3.7.1", "szepeviktor/phpstan-wordpress": "1.3.0", "wp-coding-standards/wpcs": "2.3.0" @@ -60,7 +61,7 @@ "sort-packages": true }, "extra": { - "wordpress-install-dir": "vendor/roots/wordpress" + "wordpress-install-dir": "vendor/wordpress/wordpress" }, "scripts": { "test": [ diff --git a/docker-compose.yml b/docker-compose.yml index 8d73e9f..901bd4d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,7 +12,7 @@ services: - php volumes: - ./vendor/johnbillion/plugin-infrastructure/tests/nginx.conf:/etc/nginx/templates/default.conf.template - - ./vendor/roots/wordpress:/var/www/html/:rw + - ./vendor/wordpress/wordpress:/var/www/html/:rw - ./vendor/johnbillion/plugin-infrastructure/tests/wp-config.php:/var/www/html/wp-config.php - ./:/var/www/html/wp-content/plugins/${COMPOSE_PROJECT_NAME}:rw @@ -30,7 +30,7 @@ services: - database init: true volumes: - - ./vendor/roots/wordpress:/var/www/html/:rw + - ./vendor/wordpress/wordpress:/var/www/html/:rw - ./vendor/johnbillion/plugin-infrastructure/tests/wp-config.php:/var/www/html/wp-config.php - ./vendor/johnbillion/plugin-infrastructure/tests/php-config.ini:/usr/local/etc/php/conf.d/php-config.ini - ./:/var/www/html/wp-content/plugins/${COMPOSE_PROJECT_NAME}:rw @@ -62,7 +62,7 @@ services: - php init: true volumes: - - ./vendor/roots/wordpress:/var/www/:rw + - ./vendor/wordpress/wordpress:/var/www/:rw - ./vendor/johnbillion/plugin-infrastructure/tests/wp-config.php:/var/www/wp-config.php - ./vendor/johnbillion/plugin-infrastructure/tests/php-config.ini:/usr/local/etc/php/conf.d/php-config.ini - ./:/var/www/wp-content/plugins/${COMPOSE_PROJECT_NAME}:rw From 62374ab8a6fd960c6e7418fd5de589ece99b1238 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 2 Aug 2023 21:59:21 +0100 Subject: [PATCH 217/270] Better naming for WP versions in the tests. --- .github/workflows/acceptance-tests.yml | 6 +++--- .github/workflows/integration-tests.yml | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml index 5ac386c..3927111 100644 --- a/.github/workflows/acceptance-tests.yml +++ b/.github/workflows/acceptance-tests.yml @@ -30,7 +30,7 @@ jobs: strategy: matrix: wp: - - 'dev-nightly' + - 'nightly' - '6.2' php: - '8.2' @@ -39,8 +39,8 @@ jobs: dev: - ${{ github.ref_name == 'develop' }} exclude: - # Only run the dev-nightly tests on the develop branch. - - wp: 'dev-nightly' + # Only run the nightly tests on the develop branch. + - wp: 'nightly' dev: false fail-fast: false uses: johnbillion/plugin-infrastructure/.github/workflows/reusable-acceptance-tests.yml@trunk diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 2611407..72e22df 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -31,16 +31,16 @@ jobs: strategy: matrix: wp: - - '*' - - 'dev-nightly' + - 'latest' + - 'nightly' php: - '8.2' - '7.4' dev: - ${{ github.ref_name == 'develop' }} exclude: - # Only run the dev-nightly tests on the develop branch. - - wp: 'dev-nightly' + # Only run the nightly tests on the develop branch. + - wp: 'nightly' dev: false fail-fast: false with: From 9d5c72a55eb4e2e60015841f3f97e4aaa6fe2ff5 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 2 Aug 2023 22:04:52 +0100 Subject: [PATCH 218/270] Switch back to WPBrowser because the browser rendering in WebDriver causes tests to unnecessarily fail. --- composer.json | 2 +- tests/acceptance.suite.yml | 24 ++++++------------------ 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/composer.json b/composer.json index fae7f32..c2390f8 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ "require-dev": { "codeception/module-asserts": "^1.0", "codeception/module-db": "^1.0", - "codeception/module-webdriver": "^1.0", + "codeception/module-phpbrowser": "^1.0", "codeception/util-universalframework": "^1.0", "dealerdirect/phpcodesniffer-composer-installer": "0.7.2", "ergebnis/composer-normalize": "^2", diff --git a/tests/acceptance.suite.yml b/tests/acceptance.suite.yml index ff699da..91a55ea 100644 --- a/tests/acceptance.suite.yml +++ b/tests/acceptance.suite.yml @@ -1,13 +1,13 @@ # Codeception Test Suite Configuration # # Suite for acceptance tests. -# Perform tests in browser using WPWebDriver. +# Perform tests in browser using WPBrowser. actor: AcceptanceTester modules: enabled: - - WPWebDriver - WPDb + - WPBrowser config: WPDb: dsn: 'mysql:host=localhost:%TEST_SITE_DATABASE_PORT%;dbname=plugindb' @@ -18,20 +18,8 @@ modules: dump: false populate: false cleanup: false - WPWebDriver: + WPBrowser: url: '%TEST_SITE_WP_URL%' - adminUsername: admin - adminPassword: admin - adminPath: /wp-admin - browser: chrome - host: localhost - port: '%TEST_SITE_WEBDRIVER_PORT%' - window_size: 1440x900 - capabilities: - chromeOptions: - args: [ - "--headless", - "--disable-gpu", - "--proxy-server='direct://'", - "--proxy-bypass-list=*" - ] + adminUsername: 'admin' + adminPassword: 'admin' + adminPath: '/wp-admin' From 47ab45500faa0a86859c6d94a0b65d58fb57ce21 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 2 Aug 2023 22:04:57 +0100 Subject: [PATCH 219/270] Don't need this any more. --- bin/test.sh | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100755 bin/test.sh diff --git a/bin/test.sh b/bin/test.sh deleted file mode 100755 index a448810..0000000 --- a/bin/test.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash - -# -e Exit immediately if a pipeline returns a non-zero status -# -o pipefail Produce a failure return code if any command errors -set -eo pipefail - -# Specify the directory where the WordPress installation lives: -WP_CORE_DIR="${PWD}/tests/wordpress" - -# Specify the URL for the site: -WP_URL="localhost:8000" - -# Start the PHP server: -php -S "$WP_URL" -t "$WP_CORE_DIR" -d disable_functions=mail 2>/dev/null & -PHP_SERVER_PROCESS_ID=$! - -# Run the acceptance tests: -TEST_SITE_WP_DIR=$WP_CORE_DIR \ -TEST_SITE_WP_URL="http://$WP_URL" \ - ./vendor/bin/codecept run acceptance --steps "$1" \ - || ( TESTS_EXIT_CODE=$? && kill $PHP_SERVER_PROCESS_ID && exit $TESTS_EXIT_CODE ) - -# Stop the PHP web server: -kill $PHP_SERVER_PROCESS_ID From 1e70e7ad3c5091a248107b26c988d52db369c4ee Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 6 Aug 2023 00:53:04 +0100 Subject: [PATCH 220/270] Deal with language file installation during acceptance tests. --- composer.json | 2 +- tests/acceptance/SwitchFromEnglishCest.php | 4 ---- tests/acceptance/SwitchToEnglishCest.php | 4 ---- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/composer.json b/composer.json index c2390f8..ddbca0d 100644 --- a/composer.json +++ b/composer.json @@ -73,7 +73,7 @@ "@test:acceptance" ], "test:acceptance": [ - "acceptance-tests" + "acceptance-tests --cli=\"language core install it_IT\" --cli=\"language plugin install user-switching it_IT\"" ], "test:destroy": [ "COMPOSE_PROJECT_NAME=user-switching docker compose down --volumes --remove-orphans" diff --git a/tests/acceptance/SwitchFromEnglishCest.php b/tests/acceptance/SwitchFromEnglishCest.php index 7304a4a..7edbd76 100644 --- a/tests/acceptance/SwitchFromEnglishCest.php +++ b/tests/acceptance/SwitchFromEnglishCest.php @@ -9,10 +9,6 @@ public function _before( AcceptanceTester $I ) { $I->comment( 'I need to be able to switch to user accounts that use a different language' ); $I->comment( 'And see the output of User Switching in my original language' ); - # Install language files: - $I->cli( 'language core install it_IT' ); - $I->cli( 'language plugin install user-switching it_IT' ); - $I->haveUserInDatabase( 'autore', 'author', [ 'display_name' => 'Autore', 'meta' => [ diff --git a/tests/acceptance/SwitchToEnglishCest.php b/tests/acceptance/SwitchToEnglishCest.php index b1b5506..947bbc2 100644 --- a/tests/acceptance/SwitchToEnglishCest.php +++ b/tests/acceptance/SwitchToEnglishCest.php @@ -9,10 +9,6 @@ public function _before( AcceptanceTester $I ) { $I->comment( 'I need to be able to switch between users' ); $I->comment( 'And see the output of User Switching in my original language' ); - # Install language files: - $I->cli( 'language core install it_IT' ); - $I->cli( 'language plugin install user-switching it_IT' ); - $I->haveUserInDatabase( 'admin_it', 'administrator', [ 'display_name' => 'Admin IT', 'meta' => [ From 4514a6c0d0f41a583567174e77f84147698463f5 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 6 Aug 2023 01:01:15 +0100 Subject: [PATCH 221/270] Update some expected permalinks. --- tests/acceptance/SwitchOffCest.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index 83f219d..be807a4 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -47,7 +47,7 @@ public function SwitchOffFromPublishedPostEditingScreen( AcceptanceTester $I ) { try { // WordPress >= 5.7: - $I->seeCurrentUrlEquals( '/hello-world?switched_off=true' ); + $I->seeCurrentUrlEquals( '/hello-world/?switched_off=true' ); } catch ( \PHPUnit\Framework\ExpectationFailedException $e ) { // WordPress < 5.7: $I->seeCurrentUrlEquals( '?switched_off=true' ); @@ -76,7 +76,7 @@ public function SwitchOffFromTermEditingScreen( AcceptanceTester $I ) { try { // WordPress >= 5.1: - $I->seeCurrentUrlEquals( '/category/hello?switched_off=true' ); + $I->seeCurrentUrlEquals( '/category/hello/?switched_off=true' ); } catch ( \PHPUnit\Framework\ExpectationFailedException $e ) { // WordPress < 5.1: $I->seeCurrentUrlEquals( '?switched_off=true' ); @@ -92,7 +92,7 @@ public function SwitchOffFromUserEditingScreen( AcceptanceTester $I ) { // $I->amEditingUserWithId( $id ); $I->amOnAdminPage( '/user-edit.php?user_id=' . $id ); $I->switchOff(); - $I->seeCurrentUrlEquals( '/author/example?switched_off=true' ); + $I->seeCurrentUrlEquals( '/author/example/?switched_off=true' ); $I->amLoggedOut(); } @@ -107,7 +107,7 @@ public function SwitchOffFromApprovedCommentEditingScreen( AcceptanceTester $I ) ] ); $I->amOnAdminPage( '/comment.php?action=editcomment&c=' . $commentId ); $I->switchOff(); - $I->seeCurrentUrlEquals( '/leave-a-comment?switched_off=true#comment-' . $commentId ); + $I->seeCurrentUrlEquals( '/leave-a-comment/?switched_off=true#comment-' . $commentId ); $I->amLoggedOut(); } @@ -125,7 +125,7 @@ public function SwitchOffFromUnapprovedCommentEditingScreen( AcceptanceTester $I try { // WordPress >= 5.7: - $I->seeCurrentUrlEquals( '/leave-a-comment?switched_off=true' ); + $I->seeCurrentUrlEquals( '/leave-a-comment/?switched_off=true' ); } catch ( \PHPUnit\Framework\ExpectationFailedException $e ) { // WordPress < 5.7: $I->seeCurrentUrlEquals( '?switched_off=true' ); From 2f51bb4666864ebf8eefb26eea3213f572c1087c Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 6 Aug 2023 01:10:36 +0100 Subject: [PATCH 222/270] Don't ignore the package lock. --- .gitignore | 1 - package-lock.json | 2865 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2865 insertions(+), 1 deletion(-) create mode 100644 package-lock.json diff --git a/.gitignore b/.gitignore index 136ba2b..30cde05 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ /composer.lock -/package-lock.json /vendor /node_modules /tests/_output/ diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..7141915 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2865 @@ +{ + "name": "user-switching", + "version": "1.7.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "user-switching", + "version": "1.7.0", + "license": "GPL-2.0-or-later", + "devDependencies": { + "plugin-infrastructure": "file:vendor/johnbillion/plugin-infrastructure", + "version-bump-prompt": "^6.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@actions/github": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@actions/http-client": "^1.0.3", + "@octokit/graphql": "^4.3.1", + "@octokit/rest": "^16.43.1" + } + }, + "node_modules/@actions/http-client": { + "version": "1.0.11", + "dev": true, + "license": "MIT", + "dependencies": { + "tunnel": "0.0.6" + } + }, + "node_modules/@jsdevtools/ez-spawn": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-me-maybe": "^1.0.1", + "cross-spawn": "^7.0.3", + "string-argv": "^0.3.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jsdevtools/version-bump-prompt": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jsdevtools/ez-spawn": "^3.0.4", + "command-line-args": "^5.1.1", + "detect-indent": "^6.0.0", + "detect-newline": "^3.1.0", + "globby": "^11.0.1", + "inquirer": "^7.3.3", + "log-symbols": "^4.0.0", + "semver": "^7.3.2" + }, + "bin": { + "bump": "bin/bump.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@octokit/auth-token": { + "version": "2.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^6.0.3" + } + }, + "node_modules/@octokit/core": { + "version": "4.2.4", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@octokit/auth-token": "^3.0.0", + "@octokit/graphql": "^5.0.0", + "@octokit/request": "^6.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/core/node_modules/@octokit/auth-token": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/core/node_modules/@octokit/endpoint": { + "version": "7.0.6", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/core/node_modules/@octokit/graphql": { + "version": "5.0.6", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/core/node_modules/@octokit/openapi-types": { + "version": "18.0.0", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@octokit/core/node_modules/@octokit/request": { + "version": "6.2.8", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@octokit/endpoint": "^7.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/core/node_modules/@octokit/request-error": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@octokit/types": "^9.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/core/node_modules/@octokit/types": { + "version": "9.3.2", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@octokit/openapi-types": "^18.0.0" + } + }, + "node_modules/@octokit/endpoint": { + "version": "6.0.12", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/graphql": { + "version": "4.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "12.11.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^2.0.1" + } + }, + "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": { + "version": "2.16.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": ">= 8" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "2.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^2.0.1", + "deprecation": "^2.3.1" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": { + "version": "2.16.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": ">= 8" + } + }, + "node_modules/@octokit/request": { + "version": "5.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/request-error": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "node_modules/@octokit/rest": { + "version": "16.43.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^2.4.0", + "@octokit/plugin-paginate-rest": "^1.1.1", + "@octokit/plugin-request-log": "^1.0.0", + "@octokit/plugin-rest-endpoint-methods": "2.4.0", + "@octokit/request": "^5.2.0", + "@octokit/request-error": "^1.0.2", + "atob-lite": "^2.0.0", + "before-after-hook": "^2.0.0", + "btoa-lite": "^1.0.0", + "deprecation": "^2.0.0", + "lodash.get": "^4.4.2", + "lodash.set": "^4.3.2", + "lodash.uniq": "^4.5.0", + "octokit-pagination-methods": "^1.1.0", + "once": "^1.4.0", + "universal-user-agent": "^4.0.0" + } + }, + "node_modules/@octokit/rest/node_modules/@octokit/request-error": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^2.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "node_modules/@octokit/rest/node_modules/@octokit/types": { + "version": "2.16.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": ">= 8" + } + }, + "node_modules/@octokit/rest/node_modules/universal-user-agent": { + "version": "4.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "os-name": "^3.1.0" + } + }, + "node_modules/@octokit/types": { + "version": "6.41.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^12.11.0" + } + }, + "node_modules/@types/node": { + "version": "20.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/array-back": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/atob-lite": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/btoa-lite": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/call-me-maybe": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/camelcase": { + "version": "5.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/command-line-args": { + "version": "5.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deprecation": { + "version": "2.3.1", + "dev": true, + "license": "ISC" + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/execa": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/execa/node_modules/cross-spawn": { + "version": "6.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/execa/node_modules/path-key": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/execa/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/execa/node_modules/shebang-command": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/shebang-regex": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/which": { + "version": "1.3.1", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.15.0", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-replace": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/inquirer": { + "version": "7.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.19", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.6.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/locate-path": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.set": { + "version": "4.3.2", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/macos-release": { + "version": "2.5.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "dev": true, + "license": "ISC" + }, + "node_modules/nice-try": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/node-fetch": { + "version": "2.6.11", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/octokit-pagination-methods": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-name": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "macos-release": "^2.2.0", + "windows-release": "^3.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/plugin-infrastructure": { + "resolved": "vendor/johnbillion/plugin-infrastructure", + "link": true + }, + "node_modules/pump": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/replace-in-file": { + "version": "5.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^3.0.0", + "glob": "^7.1.6", + "yargs": "^15.0.2" + }, + "bin": { + "replace-in-file": "bin/cli.js" + } + }, + "node_modules/replace-in-file/node_modules/chalk": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "6.6.7", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.5.3", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "dev": true, + "license": "ISC" + }, + "node_modules/slash": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-argv": { + "version": "0.3.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/through": { + "version": "2.3.8", + "dev": true, + "license": "MIT" + }, + "node_modules/tmp": { + "version": "0.0.33", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/tslib": { + "version": "1.14.1", + "dev": true, + "license": "0BSD" + }, + "node_modules/tunnel": { + "version": "0.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typical": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/universal-user-agent": { + "version": "6.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/version-bump-prompt": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jsdevtools/version-bump-prompt": "6.1.0" + }, + "bin": { + "bump": "bump.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-module": { + "version": "2.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/windows-release": { + "version": "3.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^1.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/y18n": { + "version": "4.0.3", + "dev": true, + "license": "ISC" + }, + "node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "15.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs-parser": { + "version": "18.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "vendor/johnbillion/plugin-infrastructure": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@actions/github": "^2", + "replace-in-file": "^5", + "semver": "^7" + }, + "engines": { + "node": ">=16" + } + } + }, + "dependencies": { + "@actions/github": { + "version": "2.2.0", + "dev": true, + "requires": { + "@actions/http-client": "^1.0.3", + "@octokit/graphql": "^4.3.1", + "@octokit/rest": "^16.43.1" + } + }, + "@actions/http-client": { + "version": "1.0.11", + "dev": true, + "requires": { + "tunnel": "0.0.6" + } + }, + "@jsdevtools/ez-spawn": { + "version": "3.0.4", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "cross-spawn": "^7.0.3", + "string-argv": "^0.3.1", + "type-detect": "^4.0.8" + } + }, + "@jsdevtools/version-bump-prompt": { + "version": "6.1.0", + "dev": true, + "requires": { + "@jsdevtools/ez-spawn": "^3.0.4", + "command-line-args": "^5.1.1", + "detect-indent": "^6.0.0", + "detect-newline": "^3.1.0", + "globby": "^11.0.1", + "inquirer": "^7.3.3", + "log-symbols": "^4.0.0", + "semver": "^7.3.2" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@octokit/auth-token": { + "version": "2.5.0", + "dev": true, + "requires": { + "@octokit/types": "^6.0.3" + } + }, + "@octokit/core": { + "version": "4.2.4", + "dev": true, + "peer": true, + "requires": { + "@octokit/auth-token": "^3.0.0", + "@octokit/graphql": "^5.0.0", + "@octokit/request": "^6.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "dependencies": { + "@octokit/auth-token": { + "version": "3.0.4", + "dev": true, + "peer": true + }, + "@octokit/endpoint": { + "version": "7.0.6", + "dev": true, + "peer": true, + "requires": { + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/graphql": { + "version": "5.0.6", + "dev": true, + "peer": true, + "requires": { + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/openapi-types": { + "version": "18.0.0", + "dev": true, + "peer": true + }, + "@octokit/request": { + "version": "6.2.8", + "dev": true, + "peer": true, + "requires": { + "@octokit/endpoint": "^7.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request-error": { + "version": "3.0.3", + "dev": true, + "peer": true, + "requires": { + "@octokit/types": "^9.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/types": { + "version": "9.3.2", + "dev": true, + "peer": true, + "requires": { + "@octokit/openapi-types": "^18.0.0" + } + } + } + }, + "@octokit/endpoint": { + "version": "6.0.12", + "dev": true, + "requires": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/graphql": { + "version": "4.8.0", + "dev": true, + "requires": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/openapi-types": { + "version": "12.11.0", + "dev": true + }, + "@octokit/plugin-paginate-rest": { + "version": "1.1.2", + "dev": true, + "requires": { + "@octokit/types": "^2.0.1" + }, + "dependencies": { + "@octokit/types": { + "version": "2.16.2", + "dev": true, + "requires": { + "@types/node": ">= 8" + } + } + } + }, + "@octokit/plugin-request-log": { + "version": "1.0.4", + "dev": true, + "requires": {} + }, + "@octokit/plugin-rest-endpoint-methods": { + "version": "2.4.0", + "dev": true, + "requires": { + "@octokit/types": "^2.0.1", + "deprecation": "^2.3.1" + }, + "dependencies": { + "@octokit/types": { + "version": "2.16.2", + "dev": true, + "requires": { + "@types/node": ">= 8" + } + } + } + }, + "@octokit/request": { + "version": "5.6.3", + "dev": true, + "requires": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request-error": { + "version": "2.1.0", + "dev": true, + "requires": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/rest": { + "version": "16.43.2", + "dev": true, + "requires": { + "@octokit/auth-token": "^2.4.0", + "@octokit/plugin-paginate-rest": "^1.1.1", + "@octokit/plugin-request-log": "^1.0.0", + "@octokit/plugin-rest-endpoint-methods": "2.4.0", + "@octokit/request": "^5.2.0", + "@octokit/request-error": "^1.0.2", + "atob-lite": "^2.0.0", + "before-after-hook": "^2.0.0", + "btoa-lite": "^1.0.0", + "deprecation": "^2.0.0", + "lodash.get": "^4.4.2", + "lodash.set": "^4.3.2", + "lodash.uniq": "^4.5.0", + "octokit-pagination-methods": "^1.1.0", + "once": "^1.4.0", + "universal-user-agent": "^4.0.0" + }, + "dependencies": { + "@octokit/request-error": { + "version": "1.2.1", + "dev": true, + "requires": { + "@octokit/types": "^2.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/types": { + "version": "2.16.2", + "dev": true, + "requires": { + "@types/node": ">= 8" + } + }, + "universal-user-agent": { + "version": "4.0.1", + "dev": true, + "requires": { + "os-name": "^3.1.0" + } + } + } + }, + "@octokit/types": { + "version": "6.41.0", + "dev": true, + "requires": { + "@octokit/openapi-types": "^12.11.0" + } + }, + "@types/node": { + "version": "20.3.1", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.2", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + } + }, + "ansi-regex": { + "version": "5.0.1", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "array-back": { + "version": "3.1.0", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "dev": true + }, + "atob-lite": { + "version": "2.0.0", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "dev": true + }, + "before-after-hook": { + "version": "2.2.3", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "btoa-lite": { + "version": "1.0.0", + "dev": true + }, + "call-me-maybe": { + "version": "1.0.2", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chardet": { + "version": "0.7.0", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-width": { + "version": "3.0.0", + "dev": true + }, + "cliui": { + "version": "6.0.0", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "color-convert": { + "version": "2.0.1", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "dev": true + }, + "command-line-args": { + "version": "5.2.1", + "dev": true, + "requires": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "decamelize": { + "version": "1.2.0", + "dev": true + }, + "deprecation": { + "version": "2.3.1", + "dev": true + }, + "detect-indent": { + "version": "6.1.0", + "dev": true + }, + "detect-newline": { + "version": "3.1.0", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "dev": true + }, + "execa": { + "version": "1.0.0", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "path-key": { + "version": "2.0.1", + "dev": true + }, + "semver": { + "version": "5.7.1", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "dev": true + }, + "which": { + "version": "1.3.1", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "external-editor": { + "version": "3.1.0", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "fast-glob": { + "version": "3.2.12", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fastq": { + "version": "1.15.0", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "figures": { + "version": "3.2.0", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "fill-range": { + "version": "7.0.1", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-replace": { + "version": "3.0.0", + "dev": true, + "requires": { + "array-back": "^3.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.2.3", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globby": { + "version": "11.1.0", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "5.2.4", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "dev": true + }, + "inquirer": { + "version": "7.3.3", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.19", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.6.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + } + }, + "is-extglob": { + "version": "2.1.1", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "dev": true + }, + "is-plain-object": { + "version": "5.0.0", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "dev": true + }, + "is-unicode-supported": { + "version": "0.1.0", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "dev": true + }, + "lodash.camelcase": { + "version": "4.3.0", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "dev": true + }, + "lodash.set": { + "version": "4.3.2", + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "macos-release": { + "version": "2.5.1", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mimic-fn": { + "version": "2.1.0", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mute-stream": { + "version": "0.0.8", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "dev": true + }, + "node-fetch": { + "version": "2.6.11", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "npm-run-path": { + "version": "2.0.2", + "dev": true, + "requires": { + "path-key": "^2.0.0" + }, + "dependencies": { + "path-key": { + "version": "2.0.1", + "dev": true + } + } + }, + "octokit-pagination-methods": { + "version": "1.1.0", + "dev": true + }, + "once": { + "version": "1.4.0", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "os-name": { + "version": "3.1.0", + "dev": true, + "requires": { + "macos-release": "^2.2.0", + "windows-release": "^3.1.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "dev": true + }, + "plugin-infrastructure": { + "version": "file:vendor/johnbillion/plugin-infrastructure", + "requires": { + "@actions/github": "^2", + "replace-in-file": "^5", + "semver": "^7" + } + }, + "pump": { + "version": "3.0.0", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "queue-microtask": { + "version": "1.2.3", + "dev": true + }, + "replace-in-file": { + "version": "5.0.2", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "glob": "^7.1.6", + "yargs": "^15.0.2" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "require-directory": { + "version": "2.1.1", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "dev": true + }, + "restore-cursor": { + "version": "3.1.0", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "reusify": { + "version": "1.0.4", + "dev": true + }, + "run-async": { + "version": "2.4.1", + "dev": true + }, + "run-parallel": { + "version": "1.2.0", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "rxjs": { + "version": "6.6.7", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safer-buffer": { + "version": "2.1.2", + "dev": true + }, + "semver": { + "version": "7.5.3", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "set-blocking": { + "version": "2.0.0", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "dev": true + }, + "signal-exit": { + "version": "3.0.7", + "dev": true + }, + "slash": { + "version": "3.0.0", + "dev": true + }, + "string-argv": { + "version": "0.3.2", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-eof": { + "version": "1.0.0", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "through": { + "version": "2.3.8", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-regex-range": { + "version": "5.0.1", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tr46": { + "version": "0.0.3", + "dev": true + }, + "tslib": { + "version": "1.14.1", + "dev": true + }, + "tunnel": { + "version": "0.0.6", + "dev": true + }, + "type-detect": { + "version": "4.0.8", + "dev": true + }, + "type-fest": { + "version": "0.21.3", + "dev": true + }, + "typical": { + "version": "4.0.0", + "dev": true + }, + "universal-user-agent": { + "version": "6.0.0", + "dev": true + }, + "version-bump-prompt": { + "version": "6.1.0", + "dev": true, + "requires": { + "@jsdevtools/version-bump-prompt": "6.1.0" + } + }, + "webidl-conversions": { + "version": "3.0.1", + "dev": true + }, + "whatwg-url": { + "version": "5.0.0", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.1", + "dev": true + }, + "windows-release": { + "version": "3.3.3", + "dev": true, + "requires": { + "execa": "^1.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "dev": true + }, + "y18n": { + "version": "4.0.3", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} From e6c2b1d1a1a0ab5fb25ac064204c40ed6a154e89 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 6 Aug 2023 01:18:26 +0100 Subject: [PATCH 223/270] Skip the build in all workflows. --- .github/workflows/acceptance-tests.yml | 1 + .github/workflows/deploy-assets.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml index 3927111..a971455 100644 --- a/.github/workflows/acceptance-tests.yml +++ b/.github/workflows/acceptance-tests.yml @@ -47,3 +47,4 @@ jobs: with: wp: ${{ matrix.wp }} php: ${{ matrix.php }} + node: false diff --git a/.github/workflows/deploy-assets.yml b/.github/workflows/deploy-assets.yml index 5d899e7..466a29b 100644 --- a/.github/workflows/deploy-assets.yml +++ b/.github/workflows/deploy-assets.yml @@ -13,6 +13,7 @@ jobs: with: plugin: user-switching readme: readme.md + node: false secrets: WPORG_SVN_USERNAME: ${{ secrets.WPORG_SVN_USERNAME }} WPORG_SVN_PASSWORD: ${{ secrets.WPORG_SVN_PASSWORD }} From f3906aac71d829f22bbd15785e08ba525bea6719 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 6 Aug 2023 01:24:48 +0100 Subject: [PATCH 224/270] Replace the Docker Compose file with a symlink to the one in the test infrastructure. --- docker-compose.yml | 85 +--------------------------------------------- 1 file changed, 1 insertion(+), 84 deletions(-) mode change 100644 => 120000 docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 901bd4d..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,84 +0,0 @@ -version: '3.1' - -services: - - server: - image: nginx:alpine - container_name: ${COMPOSE_PROJECT_NAME}-server - restart: always - ports: - - 80 - depends_on: - - php - volumes: - - ./vendor/johnbillion/plugin-infrastructure/tests/nginx.conf:/etc/nginx/templates/default.conf.template - - ./vendor/wordpress/wordpress:/var/www/html/:rw - - ./vendor/johnbillion/plugin-infrastructure/tests/wp-config.php:/var/www/html/wp-config.php - - ./:/var/www/html/wp-content/plugins/${COMPOSE_PROJECT_NAME}:rw - - php: - image: wordpressdevelop/php:${LOCAL_PHP-8.1}-fpm - container_name: ${COMPOSE_PROJECT_NAME}-php - restart: always - environment: - WORDPRESS_DB_HOST: database - WORDPRESS_DB_USER: pluginuser - WORDPRESS_DB_PASSWORD: pluginpass - WORDPRESS_DB_NAME: plugindb - WORDPRESS_DEBUG: ${LOCAL_WP_DEBUG-1} - depends_on: - - database - init: true - volumes: - - ./vendor/wordpress/wordpress:/var/www/html/:rw - - ./vendor/johnbillion/plugin-infrastructure/tests/wp-config.php:/var/www/html/wp-config.php - - ./vendor/johnbillion/plugin-infrastructure/tests/php-config.ini:/usr/local/etc/php/conf.d/php-config.ini - - ./:/var/www/html/wp-content/plugins/${COMPOSE_PROJECT_NAME}:rw - - database: - image: mariadb:10.5.8 - container_name: ${COMPOSE_PROJECT_NAME}-database - restart: always - ports: - - 3306 - environment: - MYSQL_DATABASE: plugindb - MYSQL_USER: pluginuser - MYSQL_PASSWORD: pluginpass - MYSQL_RANDOM_ROOT_PASSWORD: '1' - volumes: - - database:/var/lib/mysql:rw - - wpcli: - image: wordpressdevelop/cli:${LOCAL_PHP-8.1}-fpm - container_name: ${COMPOSE_PROJECT_NAME}-wpcli - environment: - WORDPRESS_DB_HOST: database - WORDPRESS_DB_USER: pluginuser - WORDPRESS_DB_PASSWORD: pluginpass - WORDPRESS_DB_NAME: plugindb - depends_on: - - database - - php - init: true - volumes: - - ./vendor/wordpress/wordpress:/var/www/:rw - - ./vendor/johnbillion/plugin-infrastructure/tests/wp-config.php:/var/www/wp-config.php - - ./vendor/johnbillion/plugin-infrastructure/tests/php-config.ini:/usr/local/etc/php/conf.d/php-config.ini - - ./:/var/www/wp-content/plugins/${COMPOSE_PROJECT_NAME}:rw - - chrome: - image: seleniarm/standalone-chromium - container_name: ${COMPOSE_PROJECT_NAME}-chrome - profiles: - - acceptance-tests - depends_on: - - server - ports: - - 4444 - extra_hosts: - - host.docker.internal:host-gateway - shm_size: 2gb - -volumes: - database: diff --git a/docker-compose.yml b/docker-compose.yml new file mode 120000 index 0000000..c3e1327 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1 @@ +vendor/johnbillion/plugin-infrastructure/tests/docker-compose.yml \ No newline at end of file From 8adff2a798a789fe38aeb2f328c189d6ab8a78c8 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Mon, 7 Aug 2023 17:53:10 +0100 Subject: [PATCH 225/270] Switch branch for testing. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index ddbca0d..e7594ec 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "codeception/util-universalframework": "^1.0", "dealerdirect/phpcodesniffer-composer-installer": "0.7.2", "ergebnis/composer-normalize": "^2", - "johnbillion/plugin-infrastructure": "dev-trunk", + "johnbillion/plugin-infrastructure": "dev-setup-php", "lucatume/wp-browser": "^3.0.21", "phpcompatibility/phpcompatibility-wp": "2.1.4", "phpstan/phpstan": "^1.0", From c9d89971922c2edd7fe11d4e0011feb4532af50c Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Mon, 7 Aug 2023 18:12:47 +0100 Subject: [PATCH 226/270] Switch branch again. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index e7594ec..ddbca0d 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "codeception/util-universalframework": "^1.0", "dealerdirect/phpcodesniffer-composer-installer": "0.7.2", "ergebnis/composer-normalize": "^2", - "johnbillion/plugin-infrastructure": "dev-setup-php", + "johnbillion/plugin-infrastructure": "dev-trunk", "lucatume/wp-browser": "^3.0.21", "phpcompatibility/phpcompatibility-wp": "2.1.4", "phpstan/phpstan": "^1.0", From 28a4674dfb6fbb4896aa4c7991ea37a0b59918ca Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Mon, 7 Aug 2023 18:22:20 +0100 Subject: [PATCH 227/270] Another branch switch. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index ddbca0d..aa12c72 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "codeception/util-universalframework": "^1.0", "dealerdirect/phpcodesniffer-composer-installer": "0.7.2", "ergebnis/composer-normalize": "^2", - "johnbillion/plugin-infrastructure": "dev-trunk", + "johnbillion/plugin-infrastructure": "dev-host", "lucatume/wp-browser": "^3.0.21", "phpcompatibility/phpcompatibility-wp": "2.1.4", "phpstan/phpstan": "^1.0", From b8eaf729a5ceee2967d5150411d273a24f5d9ba9 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Mon, 7 Aug 2023 18:27:22 +0100 Subject: [PATCH 228/270] Back to trunk. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index aa12c72..ddbca0d 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "codeception/util-universalframework": "^1.0", "dealerdirect/phpcodesniffer-composer-installer": "0.7.2", "ergebnis/composer-normalize": "^2", - "johnbillion/plugin-infrastructure": "dev-host", + "johnbillion/plugin-infrastructure": "dev-trunk", "lucatume/wp-browser": "^3.0.21", "phpcompatibility/phpcompatibility-wp": "2.1.4", "phpstan/phpstan": "^1.0", From 004f5280958dbdc192e42bcc905a1c555279a4e5 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Mon, 7 Aug 2023 21:13:47 +0100 Subject: [PATCH 229/270] Switch back to running the acceptance tests with WebDriver. --- composer.json | 2 +- tests/_support/AcceptanceTester.php | 7 +++++++ tests/acceptance.suite.yml | 24 ++++++++++++++++++------ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index ddbca0d..fa5ce6a 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ "require-dev": { "codeception/module-asserts": "^1.0", "codeception/module-db": "^1.0", - "codeception/module-phpbrowser": "^1.0", + "codeception/module-webdriver": "^1.0", "codeception/util-universalframework": "^1.0", "dealerdirect/phpcodesniffer-composer-installer": "0.7.2", "ergebnis/composer-normalize": "^2", diff --git a/tests/_support/AcceptanceTester.php b/tests/_support/AcceptanceTester.php index 591f383..48ae892 100644 --- a/tests/_support/AcceptanceTester.php +++ b/tests/_support/AcceptanceTester.php @@ -32,6 +32,7 @@ public function switchToUser( $user_login ) { * Switch off */ public function switchOff() { + $this->moveMouseOver( '#wp-admin-bar-my-account' ); $this->click( 'Switch Off' ); } @@ -49,6 +50,12 @@ public function switchBackTo( $user_login ) { ] ); + try { + $this->moveMouseOver( '#wp-admin-bar-my-account' ); + } catch ( \Codeception\Exception\ElementNotFound $e ) { + // Nothing. + } + $this->click( sprintf( 'Switch back to %s', $display_name diff --git a/tests/acceptance.suite.yml b/tests/acceptance.suite.yml index 91a55ea..ff699da 100644 --- a/tests/acceptance.suite.yml +++ b/tests/acceptance.suite.yml @@ -1,13 +1,13 @@ # Codeception Test Suite Configuration # # Suite for acceptance tests. -# Perform tests in browser using WPBrowser. +# Perform tests in browser using WPWebDriver. actor: AcceptanceTester modules: enabled: + - WPWebDriver - WPDb - - WPBrowser config: WPDb: dsn: 'mysql:host=localhost:%TEST_SITE_DATABASE_PORT%;dbname=plugindb' @@ -18,8 +18,20 @@ modules: dump: false populate: false cleanup: false - WPBrowser: + WPWebDriver: url: '%TEST_SITE_WP_URL%' - adminUsername: 'admin' - adminPassword: 'admin' - adminPath: '/wp-admin' + adminUsername: admin + adminPassword: admin + adminPath: /wp-admin + browser: chrome + host: localhost + port: '%TEST_SITE_WEBDRIVER_PORT%' + window_size: 1440x900 + capabilities: + chromeOptions: + args: [ + "--headless", + "--disable-gpu", + "--proxy-server='direct://'", + "--proxy-bypass-list=*" + ] From b3d2a65de63f09df360d5328af8c6b8509ef4896 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Mon, 7 Aug 2023 21:18:37 +0100 Subject: [PATCH 230/270] Don't need this back compat in the tests any more. --- tests/acceptance/SwitchOffCest.php | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index be807a4..a06c227 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -44,15 +44,7 @@ public function SwitchOffFromPublishedPostEditingScreen( AcceptanceTester $I ) { ] ); $I->amEditingPostWithId( $id ); $I->switchOff(); - - try { - // WordPress >= 5.7: - $I->seeCurrentUrlEquals( '/hello-world/?switched_off=true' ); - } catch ( \PHPUnit\Framework\ExpectationFailedException $e ) { - // WordPress < 5.7: - $I->seeCurrentUrlEquals( '?switched_off=true' ); - } - + $I->seeCurrentUrlEquals( '/hello-world/?switched_off=true' ); $I->amLoggedOut(); } @@ -122,15 +114,7 @@ public function SwitchOffFromUnapprovedCommentEditingScreen( AcceptanceTester $I ] ); $I->amOnAdminPage( '/comment.php?action=editcomment&c=' . $commentId ); $I->switchOff(); - - try { - // WordPress >= 5.7: - $I->seeCurrentUrlEquals( '/leave-a-comment/?switched_off=true' ); - } catch ( \PHPUnit\Framework\ExpectationFailedException $e ) { - // WordPress < 5.7: - $I->seeCurrentUrlEquals( '?switched_off=true' ); - } - + $I->seeCurrentUrlEquals( '/leave-a-comment/?switched_off=true' ); $I->amLoggedOut(); } } From 4554289d8a2327c09621d4dd807386970138c59b Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Mon, 7 Aug 2023 21:18:58 +0100 Subject: [PATCH 231/270] Not sure why these need adjusting but okay. --- tests/acceptance/SwitchOffCest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index a06c227..a39b799 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -14,7 +14,7 @@ public function SwitchOffFromDashboardAndBackFromFrontEnd( AcceptanceTester $I ) $I->loginAsAdmin(); $I->amOnAdminPage( '/' ); $I->switchOff(); - $I->seeCurrentUrlEquals( '?switched_off=true' ); + $I->seeCurrentUrlEquals( '/?switched_off=true' ); $I->amLoggedOut(); $I->switchBackTo( 'admin' ); @@ -26,7 +26,7 @@ public function SwitchOffFromDashboardAndBackFromLoginScreen( AcceptanceTester $ $I->loginAsAdmin(); $I->amOnAdminPage( '/' ); $I->switchOff(); - $I->seeCurrentUrlEquals( '?switched_off=true' ); + $I->seeCurrentUrlEquals( '/?switched_off=true' ); $I->amLoggedOut(); $I->amOnPage( 'wp-login.php' ); From 38b2dac5adedaf242908f833e3b3e6e7386ae239 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Mon, 7 Aug 2023 22:51:10 +0100 Subject: [PATCH 232/270] Put the block editor into a state where the items we need to interact with are actually usable. --- tests/_support/AcceptanceTester.php | 27 +++++++++++++++++++++++++++ tests/acceptance/SwitchOffCest.php | 2 ++ 2 files changed, 29 insertions(+) diff --git a/tests/_support/AcceptanceTester.php b/tests/_support/AcceptanceTester.php index 48ae892..f1d0d54 100644 --- a/tests/_support/AcceptanceTester.php +++ b/tests/_support/AcceptanceTester.php @@ -16,6 +16,33 @@ class AcceptanceTester extends \Codeception\Actor { use _generated\AcceptanceTesterActions; + /** + * Put the block editor into a state where the items we need to interact with are + * actually usable. + * + * @return void + */ + public function amNotUsingTheEditorForTheFirstTime() { + $key = sprintf( + '%spersisted_preferences', + $this->grabTablePrefix() + ); + $value = [ + 'core/edit-post' => [ + 'fullscreenMode' => false, + 'welcomeGuide' => false, + ], + ]; + + $this->haveUserMetaInDatabase( + 1, + $key, + [ + $value, + ], + ); + } + /** * Switch to the specified user * diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index a39b799..d70ce95 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -42,6 +42,7 @@ public function SwitchOffFromPublishedPostEditingScreen( AcceptanceTester $I ) { 'post_status' => 'publish', 'post_name' => 'hello-world', ] ); + $I->amNotUsingTheEditorForTheFirstTime(); $I->amEditingPostWithId( $id ); $I->switchOff(); $I->seeCurrentUrlEquals( '/hello-world/?switched_off=true' ); @@ -54,6 +55,7 @@ public function SwitchOffFromDraftPostEditingScreen( AcceptanceTester $I ) { 'post_status' => 'draft', 'post_name' => 'hello-world', ] ); + $I->amNotUsingTheEditorForTheFirstTime(); $I->amEditingPostWithId( $id ); $I->switchOff(); $I->seeCurrentUrlEquals( '?switched_off=true' ); From bd7bcb6b7ca458ffe5c80bd726c45c9e24344682 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Mon, 7 Aug 2023 22:56:18 +0100 Subject: [PATCH 233/270] Update some URL expectations now that the history state changes are being respected. --- tests/acceptance/SwitchOffCest.php | 4 ++-- tests/acceptance/SwitchUserCest.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index d70ce95..4228fc8 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -31,7 +31,7 @@ public function SwitchOffFromDashboardAndBackFromLoginScreen( AcceptanceTester $ $I->amOnPage( 'wp-login.php' ); $I->switchBackTo( 'admin' ); - $I->seeCurrentUrlEquals( '/wp-admin/users.php?user_switched=true&switched_back=true' ); + $I->seeCurrentUrlEquals( '/wp-admin/users.php' ); $I->seeAdminSuccessNotice( 'Switched back to admin.' ); $I->amLoggedInAs( 'admin' ); } @@ -58,7 +58,7 @@ public function SwitchOffFromDraftPostEditingScreen( AcceptanceTester $I ) { $I->amNotUsingTheEditorForTheFirstTime(); $I->amEditingPostWithId( $id ); $I->switchOff(); - $I->seeCurrentUrlEquals( '?switched_off=true' ); + $I->seeCurrentUrlEquals( '/?switched_off=true' ); $I->amLoggedOut(); } diff --git a/tests/acceptance/SwitchUserCest.php b/tests/acceptance/SwitchUserCest.php index 93cede6..8cd77f7 100644 --- a/tests/acceptance/SwitchUserCest.php +++ b/tests/acceptance/SwitchUserCest.php @@ -15,7 +15,7 @@ public function SwitchToEditorThenBackFromFrontEnd( AcceptanceTester $I ) { $I->haveUserInDatabase( 'editor', 'editor' ); $I->switchToUser( 'editor' ); - $I->seeCurrentUrlEquals( '/wp-admin/?user_switched=true' ); + $I->seeCurrentUrlEquals( '/wp-admin/' ); $I->seeAdminSuccessNotice( 'Switched to editor.' ); $I->amLoggedInAs( 'editor' ); @@ -30,13 +30,13 @@ public function SwitchToEditorThenBackFromAdminArea( AcceptanceTester $I ) { $I->haveUserInDatabase( 'editor', 'editor' ); $I->switchToUser( 'editor' ); - $I->seeCurrentUrlEquals( '/wp-admin/?user_switched=true' ); + $I->seeCurrentUrlEquals( '/wp-admin/' ); $I->seeAdminSuccessNotice( 'Switched to editor.' ); $I->amLoggedInAs( 'editor' ); $I->amOnAdminPage( 'tools.php' ); $I->switchBackTo( 'admin' ); - $I->seeCurrentUrlEquals( '/wp-admin/tools.php?user_switched=true&switched_back=true' ); + $I->seeCurrentUrlEquals( '/wp-admin/tools.php' ); $I->seeAdminSuccessNotice( 'Switched back to admin.' ); $I->amLoggedInAs( 'admin' ); } From f1710c705de86ab6b39296492bf20494f6585da8 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Mon, 7 Aug 2023 23:49:24 +0100 Subject: [PATCH 234/270] Meta and docs updates. --- .gitattributes | 6 ++--- CONTRIBUTING.md | 70 ++++++++++++++++++++++++++++++++----------------- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/.gitattributes b/.gitattributes index 28fe199..e73fc07 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,19 +4,17 @@ /.git export-ignore /.github export-ignore /.wordpress-org export-ignore -/bin export-ignore /node_modules export-ignore /tests export-ignore /vendor export-ignore # Files -/.gitattributes export-ignore /.editorconfig export-ignore +/.gitattributes export-ignore /.gitignore export-ignore /.npmrc export-ignore /.nvmrc export-ignore -/assets/*.map export-ignore -/assets/*.scss export-ignore +/CODE_OF_CONDUCT.md export-ignore /codeception.dist.yml export-ignore /composer.lock export-ignore /CONTRIBUTING.md export-ignore diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index df39be1..cc1b0fd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,14 +6,6 @@ Bug reports, code contributions, and general feedback are very welcome. These should be submitted through [the GitHub repository](https://github.com/johnbillion/user-switching). Development happens in the `develop` branch, and any pull requests should be made against that branch please. -* [Reviews on WordPress.org](#reviews-on-wordpressorg) -* [Reporting Security Issues](#reporting-security-issues) -* [Inclusivity and Code of Conduct](#inclusivity-and-code-of-conduct) -* [Setting up Locally](#setting-up-locally) -* [Running the Tests](#running-the-tests) -* [Releasing a New Version](#releasing-a-new-version) -* [Ethical Open Source](#ethical-open-source) - ## Reviews on WordPress.org If you enjoy using User Switching I would greatly appreciate it if you left a positive review on the WordPress.org Plugin Directory. This is the fastest and easiest way to contribute to User Switching 😄. @@ -35,43 +27,73 @@ You can clone this repo and activate it like a normal WordPress plugin. If you w ### Prerequisites * [Composer](https://getcomposer.org/) -* A local installation of MariaDB or MySQL +* [Docker Desktop](https://www.docker.com/desktop) to run the tests ### Setup -1. Install the PHP dependencies: +Install the PHP dependencies: - composer install + composer install -2. Check the MySQL database credentials in the `tests/.env` file and amend them as necessary. +## Running the Tests -**Important:** Ensure you use a separate test database (eg. `wordpress_test`) because, just like the WordPress test suite, the database will be wiped clean with every test run. +The test suite includes acceptance tests which run in a Docker container. Ensure Docker Desktop is running, then start the containers with: -## Running the Tests + composer test:start -To run the whole test suite: +To run the whole test suite which includes integration tests, acceptance tests, linting, and static analysis: composer test -To run just the integration tests: +To run tests individually, run one of: composer test:integration + composer test:acceptance + composer test:phpcs + composer test:phpstan -To run just the coding standards checks: +To stop the Docker containers: - composer test:phpcs + composer test:stop + +## Releasing a New Version -To run just the static analysis: +These are the steps to take to release a new version of User Switching (for contributors who have push access to the GitHub repo). - composer test:phpstan +### Prior to Release -To run just the acceptance tests: +1. Check [the milestone on GitHub](https://github.com/johnbillion/user-switching/milestones) for open issues or PRs. Fix or reassign as necessary. +1. If this is a non-patch release, check issues and PRs assigned to the patch or minor milestones that will get skipped. Reassign as necessary. +1. Ensure you're on the `develop` branch and all the changes for this release have been merged in. +1. Ensure both `readme.md` contains up to date descriptions, "Tested up to" versions, FAQs, screenshots, etc. +1. Ensure `.gitattributes` is up to date with all files that shouldn't be part of the build. + - To do this, run `git archive --output=user-switching.zip HEAD` then check the contents for files that shouldn't be part of the package. +1. Run `composer test` and ensure everything passes. +1. Run `git push origin develop` (if necessary) and ensure CI is passing. +1. Prepare a changelog for [the Releases page on GitHub](https://github.com/johnbillion/user-switching/releases). - composer test:acceptance +### For Release -## Releasing a New Version +1. Bump the plugin version number: + - `npm run bump:patch` for a patch release (1.2.3 => 1.2.4) + - `npm run bump:minor` for a minor release (1.2.3 => 1.3.0) + - `npm run bump:major` for a major release (1.2.3 => 2.0.0) +1. `git push origin develop:release` +1. Wait for [the Build action](https://github.com/johnbillion/user-switching/actions/workflows/build.yml) to complete +1. Enter the changelog into [the release on GitHub](https://github.com/johnbillion/user-switching/releases) and publish it. + +### Post Release + +Publishing a release on GitHub triggers an action which deploys the release to the WordPress.org Plugin Directory. No need to touch Subversion. + +New milestones are automatically created for the next major, minor, and patch releases where appropriate. + +1. Close the milestone. +1. If this is a non-patch release, manually delete any [unused patch and minor milestones on GitHub](https://github.com/johnbillion/user-switching/milestones). +1. Check the new version has appeared [on the WordPress.org plugin page](https://wordpress.org/plugins/user-switching/) (it'll take a few minutes). +1. Resolve relevant threads on [the plugin's support forums](https://wordpress.org/support/plugin/user-switching/). -User Switching gets automatically deployed to the WordPress.org Plugin Directory whenever a new release is published on GitHub. +### Asset Updates Assets such as screenshots and banners are stored in the `.wordpress-org` directory. These get deployed as part of the automated release process too. From e62c5ec4b37e915ba112d961f1544c32518c329e Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 16 Aug 2023 22:34:02 +0100 Subject: [PATCH 235/270] Skip the vendor directory during deployment. --- .github/workflows/deploy-assets.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy-assets.yml b/.github/workflows/deploy-assets.yml index 466a29b..f76d5fe 100644 --- a/.github/workflows/deploy-assets.yml +++ b/.github/workflows/deploy-assets.yml @@ -14,6 +14,7 @@ jobs: plugin: user-switching readme: readme.md node: false + vendor: false secrets: WPORG_SVN_USERNAME: ${{ secrets.WPORG_SVN_USERNAME }} WPORG_SVN_PASSWORD: ${{ secrets.WPORG_SVN_PASSWORD }} From 6baf8cc2f8b62e1a8bce26872d883e358b7213d7 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 16 Aug 2023 22:34:17 +0100 Subject: [PATCH 236/270] Update the deployment instructions. --- CONTRIBUTING.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cc1b0fd..173df28 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,7 +65,7 @@ These are the steps to take to release a new version of User Switching (for cont 1. Check [the milestone on GitHub](https://github.com/johnbillion/user-switching/milestones) for open issues or PRs. Fix or reassign as necessary. 1. If this is a non-patch release, check issues and PRs assigned to the patch or minor milestones that will get skipped. Reassign as necessary. 1. Ensure you're on the `develop` branch and all the changes for this release have been merged in. -1. Ensure both `readme.md` contains up to date descriptions, "Tested up to" versions, FAQs, screenshots, etc. +1. Ensure `readme.md` contains up to date descriptions, "Tested up to" versions, FAQs, screenshots, etc. 1. Ensure `.gitattributes` is up to date with all files that shouldn't be part of the build. - To do this, run `git archive --output=user-switching.zip HEAD` then check the contents for files that shouldn't be part of the package. 1. Run `composer test` and ensure everything passes. @@ -78,8 +78,9 @@ These are the steps to take to release a new version of User Switching (for cont - `npm run bump:patch` for a patch release (1.2.3 => 1.2.4) - `npm run bump:minor` for a minor release (1.2.3 => 1.3.0) - `npm run bump:major` for a major release (1.2.3 => 2.0.0) -1. `git push origin develop:release` -1. Wait for [the Build action](https://github.com/johnbillion/user-switching/actions/workflows/build.yml) to complete +1. `git push origin develop` +1. `git tag x.y.z` +1. `git push origin --tags` 1. Enter the changelog into [the release on GitHub](https://github.com/johnbillion/user-switching/releases) and publish it. ### Post Release From 2bbc72eb79f35cb25e414b69d4cd7e2d8cbfbf02 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 16 Aug 2023 22:42:45 +0100 Subject: [PATCH 237/270] Update some testing versions. --- .github/workflows/acceptance-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml index a971455..24222ef 100644 --- a/.github/workflows/acceptance-tests.yml +++ b/.github/workflows/acceptance-tests.yml @@ -31,11 +31,11 @@ jobs: matrix: wp: - 'nightly' - - '6.2' + - 'latest' php: - '8.2' - '7.4' - - '5.6' + - '7.0' dev: - ${{ github.ref_name == 'develop' }} exclude: From a4e92d43e23a17f1ba4233e354f2851b883b6fc0 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 16 Aug 2023 22:44:26 +0100 Subject: [PATCH 238/270] Meta updates. --- readme.md | 2 +- user-switching.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 926c0d3..eb9b265 100644 --- a/readme.md +++ b/readme.md @@ -2,7 +2,7 @@ Stable tag: 1.7.0 Requires at least: 3.7 -Tested up to: 6.0 +Tested up to: 6.3 Requires PHP: 5.3 License: GPL v2 or later Tags: users, user switching, fast user switching, multisite, woocommerce, buddypress, bbpress diff --git a/user-switching.php b/user-switching.php index 1781baa..10d0bbd 100644 --- a/user-switching.php +++ b/user-switching.php @@ -5,7 +5,7 @@ * @package user-switching * @link https://github.com/johnbillion/user-switching * @author John Blackbourn - * @copyright 2009-2022 John Blackbourn + * @copyright 2009-2023 John Blackbourn * @license GPL v2 or later * * Plugin Name: User Switching From db22e06ff22e50b987f2b1e3166b2e5905eb4c20 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 16 Aug 2023 22:50:13 +0100 Subject: [PATCH 239/270] Remove this symlink. --- docker-compose.yml | 1 - 1 file changed, 1 deletion(-) delete mode 120000 docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 120000 index c3e1327..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1 +0,0 @@ -vendor/johnbillion/plugin-infrastructure/tests/docker-compose.yml \ No newline at end of file From 85290924645bc5caa9c5d6582cf937d6daa41607 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Wed, 16 Aug 2023 22:54:05 +0100 Subject: [PATCH 240/270] Re-add the Docker config. --- docker-compose.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..69d0be5 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,6 @@ +version: '3.1' + +include: + - + path: vendor/johnbillion/plugin-infrastructure/tests/docker-compose.yml + project_directory: . From cc2b0f19eb79d24738c4e7a1fe181759e7c74c86 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 17 Aug 2023 17:30:09 +0100 Subject: [PATCH 241/270] Readme updates. --- readme.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index eb9b265..df80849 100644 --- a/readme.md +++ b/readme.md @@ -15,7 +15,7 @@ Instant switching between user accounts in WordPress. [![](https://img.shields.io/badge/ethical-open%20source-4baaaa.svg?style=flat-square)](#ethical-open-source) [![](https://img.shields.io/wordpress/plugin/installs/user-switching?style=flat-square)](https://wordpress.org/plugins/user-switching/) -[![](https://img.shields.io/github/workflow/status/johnbillion/user-switching/Test/develop?style=flat-square)](https://github.com/johnbillion/user-switching/actions) +[![](https://img.shields.io/github/actions/workflow/status/johnbillion/user-switching/integration-tests.yml?branch=develop&style=flat-square)](https://github.com/johnbillion/user-switching/actions) ## Description @@ -26,7 +26,9 @@ This plugin allows you to quickly swap between user accounts in WordPress at the * Switch user: Instantly switch to any user account from the *Users* screen. * Switch back: Instantly switch back to your originating account. * Switch off: Log out of your account but retain the ability to instantly switch back in again. - * Compatible with Multisite, WooCommerce, BuddyPress, bbPress, and most two-factor authentication plugins. + * Compatible with Multisite, WooCommerce, BuddyPress, and bbPress. + * Compatible with most two-factor authentication solutions (see the [FAQ](https://wordpress.org/plugins/user-switching/faq/) for more info). + * Approved for use on enterprise-grade WordPress platforms such as Altis and WordPress VIP. ### Security @@ -36,7 +38,6 @@ This plugin allows you to quickly swap between user accounts in WordPress at the * Implements the nonce security system in WordPress, meaning only those who intend to switch users can switch. * Full support for user session validation where appropriate. * Full support for HTTPS. - * Approved for use on enterprise-grade WordPress platforms such as Altis and WordPress.com VIP. ### Usage From 0fc92fc509667a8cf1cf552adbfb3ebf42ea88de Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 17 Aug 2023 18:51:36 +0100 Subject: [PATCH 242/270] Be explicit about WordPress test versions. --- .github/workflows/acceptance-tests.yml | 4 +++- .github/workflows/integration-tests.yml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml index 24222ef..f6e158f 100644 --- a/.github/workflows/acceptance-tests.yml +++ b/.github/workflows/acceptance-tests.yml @@ -31,7 +31,9 @@ jobs: matrix: wp: - 'nightly' - - 'latest' + - '6.3' + - '6.2' + - '6.1' php: - '8.2' - '7.4' diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 72e22df..1091eb6 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -31,8 +31,10 @@ jobs: strategy: matrix: wp: - - 'latest' - 'nightly' + - '6.3' + - '6.2' + - '6.1' php: - '8.2' - '7.4' From 7d24139c5a7d9ee30668a55013faabc369f7a9bd Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 19 Aug 2023 00:20:29 +0100 Subject: [PATCH 243/270] Fix up the names of the integration tests. --- tests/integration/{authTest.php => authenticationTest.php} | 2 +- tests/integration/{capsTest.php => capabilitiesTest.php} | 2 +- tests/integration/pluginTest.php | 2 +- tests/integration/sessionsTest.php | 2 +- tests/integration/switchingTest.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename tests/integration/{authTest.php => authenticationTest.php} (98%) rename tests/integration/{capsTest.php => capabilitiesTest.php} (99%) diff --git a/tests/integration/authTest.php b/tests/integration/authenticationTest.php similarity index 98% rename from tests/integration/authTest.php rename to tests/integration/authenticationTest.php index 5a32663..0c40416 100644 --- a/tests/integration/authTest.php +++ b/tests/integration/authenticationTest.php @@ -9,7 +9,7 @@ /** * @covers \user_switching::authenticate_old_user */ -class Authentication extends Test { +class AuthenticationTest extends Test { public function testValidCookiePassesAuthentication() { $expiry = time() + 172800; diff --git a/tests/integration/capsTest.php b/tests/integration/capabilitiesTest.php similarity index 99% rename from tests/integration/capsTest.php rename to tests/integration/capabilitiesTest.php index 781de39..e49f282 100644 --- a/tests/integration/capsTest.php +++ b/tests/integration/capabilitiesTest.php @@ -8,7 +8,7 @@ * @covers \user_switching::filter_user_has_cap * @covers \user_switching::filter_map_meta_cap */ -class Capabilities extends Test { +class CapabilitiesTest extends Test { /** * @return array> diff --git a/tests/integration/pluginTest.php b/tests/integration/pluginTest.php index 71f1228..fb598e4 100644 --- a/tests/integration/pluginTest.php +++ b/tests/integration/pluginTest.php @@ -4,7 +4,7 @@ namespace UserSwitching\Tests; -class Readme extends Test { +class PluginTest extends Test { /** * @var ?array */ diff --git a/tests/integration/sessionsTest.php b/tests/integration/sessionsTest.php index a55d9e3..e04babd 100644 --- a/tests/integration/sessionsTest.php +++ b/tests/integration/sessionsTest.php @@ -7,7 +7,7 @@ use user_switching; use WP_Session_Tokens; -class Sessions extends Test { +class SessionsTest extends Test { /** * @covers \switch_to_user diff --git a/tests/integration/switchingTest.php b/tests/integration/switchingTest.php index 0d38645..2beb005 100644 --- a/tests/integration/switchingTest.php +++ b/tests/integration/switchingTest.php @@ -6,7 +6,7 @@ use user_switching; -class Switching extends Test { +class SwitchingTest extends Test { /** * @var int|false From 4a46574528fda73b9459bfeb7c0dd5089267f7f9 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 19 Aug 2023 00:24:42 +0100 Subject: [PATCH 244/270] We're going to the moon. --- .github/workflows/acceptance-tests.yml | 3 +- composer.json | 2 +- phpcs.xml.dist | 13 +-- readme.md | 4 +- user-switching.php | 151 ++++++++++++------------- 5 files changed, 76 insertions(+), 97 deletions(-) diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml index f6e158f..285d885 100644 --- a/.github/workflows/acceptance-tests.yml +++ b/.github/workflows/acceptance-tests.yml @@ -33,11 +33,10 @@ jobs: - 'nightly' - '6.3' - '6.2' - - '6.1' php: - '8.2' - '7.4' - - '7.0' + - '7.2' dev: - ${{ github.ref_name == 'develop' }} exclude: diff --git a/composer.json b/composer.json index fa5ce6a..bef4ddc 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ } ], "require": { - "php": ">=5.3", + "php": ">=7.2", "composer/installers": "^1.0 || ^2.0" }, "require-dev": { diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 37b2ebb..82af8d3 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -1,7 +1,7 @@ - + - - - - - - - @@ -62,7 +53,7 @@ - + diff --git a/readme.md b/readme.md index df80849..e661263 100644 --- a/readme.md +++ b/readme.md @@ -1,9 +1,9 @@ # User Switching Stable tag: 1.7.0 -Requires at least: 3.7 +Requires at least: 5.1 Tested up to: 6.3 -Requires PHP: 5.3 +Requires PHP: 7.2 License: GPL v2 or later Tags: users, user switching, fast user switching, multisite, woocommerce, buddypress, bbpress Contributors: johnbillion diff --git a/user-switching.php b/user-switching.php index 10d0bbd..4d26ec5 100644 --- a/user-switching.php +++ b/user-switching.php @@ -17,7 +17,7 @@ * Text Domain: user-switching * Domain Path: /languages/ * Network: true - * Requires PHP: 5.3 + * Requires PHP: 7.2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -177,11 +177,7 @@ public function action_init() { // We're attempting to switch to another user: case 'switch_to_user': - if ( isset( $_REQUEST['user_id'] ) ) { - $user_id = absint( $_REQUEST['user_id'] ); - } else { - $user_id = 0; - } + $user_id = absint( $_REQUEST['user_id'] ?? 0 ); // Check authentication: if ( ! current_user_can( 'switch_to_user', $user_id ) ) { @@ -324,7 +320,7 @@ protected static function get_redirect( WP_User $new_user = null, WP_User $old_u $term = get_term( absint( $_GET['redirect_to_term'] ) ); $redirect_type = self::REDIRECT_TYPE_TERM; - if ( ( $term instanceof WP_Term ) && function_exists( 'is_taxonomy_viewable' ) && is_taxonomy_viewable( $term->taxonomy ) ) { + if ( ( $term instanceof WP_Term ) && is_taxonomy_viewable( $term->taxonomy ) ) { $link = get_term_link( $term ); if ( is_string( $link ) ) { @@ -402,60 +398,57 @@ public function action_admin_notices() { if ( $old_user ) { $switched_locale = false; $lang_attr = ''; - - if ( function_exists( 'get_user_locale' ) ) { - $locale = get_user_locale( $old_user ); - $switched_locale = switch_to_locale( $locale ); - $lang_attr = str_replace( '_', '-', $locale ); - } + $locale = get_user_locale( $old_user ); + $switched_locale = switch_to_locale( $locale ); + $lang_attr = str_replace( '_', '-', $locale ); ?>
    ', - esc_attr( $lang_attr ) - ); - } else { - echo '

    '; - } + if ( $lang_attr ) { + printf( + '

    ', + esc_attr( $lang_attr ) + ); + } else { + echo '

    '; + } ?> urlencode( self::current_url() ), - ), self::switch_back_url( $old_user ) ); - - $message .= sprintf( - ' %s.', - esc_url( $switch_back_url ), - esc_html( self::switch_back_message( $old_user ) ) - ); - - /** - * Filters the contents of the message that's displayed to switched users in the admin area. - * - * @since 1.1.0 - * - * @param string $message The message displayed to the switched user. - * @param WP_User $user The current user object. - * @param WP_User $old_user The old user object. - * @param string $switch_back_url The switch back URL. - * @param bool $just_switched Whether the user made the switch on this page request. - */ - $message = apply_filters( 'user_switching_switched_message', $message, $user, $old_user, $switch_back_url, $just_switched ); - - echo wp_kses( $message, array( - 'a' => array( - 'href' => array(), - ), - ) ); + $message = ''; + $just_switched = isset( $_GET['user_switched'] ); + if ( $just_switched ) { + $message = esc_html( self::switched_to_message( $user ) ); + } + $switch_back_url = add_query_arg( array( + 'redirect_to' => rawurlencode( self::current_url() ), + ), self::switch_back_url( $old_user ) ); + + $message .= sprintf( + ' %s.', + esc_url( $switch_back_url ), + esc_html( self::switch_back_message( $old_user ) ) + ); + + /** + * Filters the contents of the message that's displayed to switched users in the admin area. + * + * @since 1.1.0 + * + * @param string $message The message displayed to the switched user. + * @param WP_User $user The current user object. + * @param WP_User $old_user The old user object. + * @param string $switch_back_url The switch back URL. + * @param bool $just_switched Whether the user made the switch on this page request. + */ + $message = apply_filters( 'user_switching_switched_message', $message, $user, $old_user, $switch_back_url, $just_switched ); + + echo wp_kses( $message, array( + 'a' => array( + 'href' => array(), + ), + ) ); ?>

    @@ -468,11 +461,11 @@ public function action_admin_notices() {

    @@ -546,7 +539,7 @@ public function action_admin_bar_menu( WP_Admin_Bar $wp_admin_bar ) { 'id' => 'switch-back', 'title' => esc_html( self::switch_back_message( $old_user ) ), 'href' => add_query_arg( array( - 'redirect_to' => urlencode( self::current_url() ), + 'redirect_to' => rawurlencode( self::current_url() ), ), self::switch_back_url( $old_user ) ), ) ); } @@ -554,7 +547,7 @@ public function action_admin_bar_menu( WP_Admin_Bar $wp_admin_bar ) { if ( current_user_can( 'switch_off' ) ) { $url = self::switch_off_url( wp_get_current_user() ); $redirect_to = is_admin() ? self::get_admin_redirect_to() : array( - 'redirect_to' => urlencode( self::current_url() ), + 'redirect_to' => rawurlencode( self::current_url() ), ); if ( is_array( $redirect_to ) ) { @@ -577,7 +570,7 @@ public function action_admin_bar_menu( WP_Admin_Bar $wp_admin_bar ) { 'id' => 'author-switch-back', 'title' => esc_html( self::switch_back_message( $old_user ) ), 'href' => add_query_arg( array( - 'redirect_to' => urlencode( self::current_url() ), + 'redirect_to' => rawurlencode( self::current_url() ), ), self::switch_back_url( $old_user ) ), ) ); } elseif ( current_user_can( 'switch_to_user', get_queried_object_id() ) ) { @@ -586,7 +579,7 @@ public function action_admin_bar_menu( WP_Admin_Bar $wp_admin_bar ) { 'id' => 'author-switch-to', 'title' => esc_html__( 'Switch To', 'user-switching' ), 'href' => add_query_arg( array( - 'redirect_to' => urlencode( self::current_url() ), + 'redirect_to' => rawurlencode( self::current_url() ), ), self::switch_to_url( get_queried_object() ) ), ) ); } @@ -636,7 +629,7 @@ public function action_wp_meta() { if ( $old_user instanceof WP_User ) { $url = add_query_arg( array( - 'redirect_to' => urlencode( self::current_url() ), + 'redirect_to' => rawurlencode( self::current_url() ), ), self::switch_back_url( $old_user ) ); printf( '
  • %s
  • ', @@ -671,7 +664,7 @@ public function action_wp_footer() { if ( $old_user instanceof WP_User ) { $url = add_query_arg( array( - 'redirect_to' => urlencode( self::current_url() ), + 'redirect_to' => rawurlencode( self::current_url() ), ), self::switch_back_url( $old_user ) ); printf( '

    %s

    ', @@ -699,7 +692,7 @@ public function filter_login_message( $message ) { ), $url ); } elseif ( ! empty( $_REQUEST['redirect_to'] ) ) { $url = add_query_arg( array( - 'redirect_to' => urlencode( wp_unslash( $_REQUEST['redirect_to'] ) ), + 'redirect_to' => rawurlencode( wp_unslash( $_REQUEST['redirect_to'] ) ), ), $url ); } @@ -764,7 +757,7 @@ public function action_bp_button() { } $link = add_query_arg( array( - 'redirect_to' => urlencode( bp_core_get_user_domain( $user->ID ) ), + 'redirect_to' => rawurlencode( bp_core_get_user_domain( $user->ID ) ), ), $link ); $components = array_keys( buddypress()->active_components ); @@ -797,7 +790,7 @@ public function action_bbpress_button() { } $link = add_query_arg( array( - 'redirect_to' => urlencode( bbp_get_user_profile_url( $user->ID ) ), + 'redirect_to' => rawurlencode( bbp_get_user_profile_url( $user->ID ) ), ), $link ); echo '
      '; @@ -979,15 +972,11 @@ public static function current_url() { /** * Removes a list of common confirmation-style query args from a URL. * - * @param string $url A URL. + * @param string $url A URL. * @return string The URL with query args removed. */ public static function remove_query_args( $url ) { - if ( function_exists( 'wp_removable_query_args' ) ) { - $url = remove_query_arg( wp_removable_query_args(), $url ); - } - - return $url; + return remove_query_arg( wp_removable_query_args(), $url ); } /** @@ -1000,7 +989,7 @@ public static function remove_query_args( $url ) { * @return bool Should the old user cookie be secure? */ public static function secure_olduser_cookie() { - return ( is_ssl() && ( 'https' === parse_url( home_url(), PHP_URL_SCHEME ) ) ); + return ( is_ssl() && ( 'https' === wp_parse_url( home_url(), PHP_URL_SCHEME ) ) ); } /** @@ -1011,7 +1000,7 @@ public static function secure_olduser_cookie() { * @return bool Whether the auth cookie should be secure. */ public static function secure_auth_cookie() { - return ( is_ssl() && ( 'https' === parse_url( wp_login_url(), PHP_URL_SCHEME ) ) ); + return ( is_ssl() && ( 'https' === wp_parse_url( wp_login_url(), PHP_URL_SCHEME ) ) ); } /** @@ -1038,7 +1027,7 @@ public function action_woocommerce_order_details( WC_Order $order ) { } $url = add_query_arg( array( - 'redirect_to' => urlencode( $order->get_view_order_url() ), + 'redirect_to' => rawurlencode( $order->get_view_order_url() ), ), self::switch_to_url( $user ) ); printf( @@ -1241,7 +1230,7 @@ function user_switching_set_olduser_cookie( $old_user_id, $pop = false, $token = array_push( $auth_cookie, wp_generate_auth_cookie( $old_user_id, $expiration, $scheme, $token ) ); } - $auth_cookie = json_encode( $auth_cookie ); + $auth_cookie = wp_json_encode( $auth_cookie ); if ( false === $auth_cookie ) { return; @@ -1396,7 +1385,7 @@ function switch_to_user( $user_id, $remember = false, $set_old_user = true ) { } $old_user_id = ( is_user_logged_in() ) ? get_current_user_id() : false; - $old_token = function_exists( 'wp_get_session_token' ) ? wp_get_session_token() : ''; + $old_token = wp_get_session_token(); $auth_cookies = user_switching_get_auth_cookie(); $auth_cookie = end( $auth_cookies ); $cookie_parts = $auth_cookie ? wp_parse_auth_cookie( $auth_cookie ) : false; @@ -1407,7 +1396,7 @@ function switch_to_user( $user_id, $remember = false, $set_old_user = true ) { user_switching_set_olduser_cookie( $old_user_id, false, $old_token ); } else { // Switching back, either after being switched off or after being switched to another user - $new_token = ( $cookie_parts && isset( $cookie_parts['token'] ) ) ? $cookie_parts['token'] : ''; + $new_token = $cookie_parts['token'] ?? ''; user_switching_clear_olduser_cookie( false ); } @@ -1487,7 +1476,7 @@ function switch_off_user() { return false; } - $old_token = function_exists( 'wp_get_session_token' ) ? wp_get_session_token() : ''; + $old_token = wp_get_session_token(); user_switching_set_olduser_cookie( $old_user_id, false, $old_token ); wp_clear_auth_cookie(); From e236c01d701572d90309179022ee31668784744b Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 20 Aug 2023 17:23:17 +0100 Subject: [PATCH 245/270] Bish bash bosh. --- .github/workflows/acceptance-tests.yml | 2 ++ .github/workflows/integration-tests.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml index 285d885..a6ca443 100644 --- a/.github/workflows/acceptance-tests.yml +++ b/.github/workflows/acceptance-tests.yml @@ -35,6 +35,8 @@ jobs: - '6.2' php: - '8.2' + - '8.1' + - '8.0' - '7.4' - '7.2' dev: diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 1091eb6..c66fa51 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -37,6 +37,8 @@ jobs: - '6.1' php: - '8.2' + - '8.1' + - '8.0' - '7.4' dev: - ${{ github.ref_name == 'develop' }} From f5de167467fd92d131f194517d2137111b93155b Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 20 Aug 2023 17:41:10 +0100 Subject: [PATCH 246/270] Normalize these. --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index bef4ddc..24cefe7 100644 --- a/composer.json +++ b/composer.json @@ -50,10 +50,10 @@ }, "config": { "allow-plugins": { + "composer/installers": true, "dealerdirect/phpcodesniffer-composer-installer": true, "ergebnis/composer-normalize": true, - "roots/wordpress-core-installer": true, - "composer/installers": true + "roots/wordpress-core-installer": true }, "classmap-authoritative": true, "preferred-install": "dist", From c762ac9e26fb6a7de9540b223da2a6d72c5508c6 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sun, 20 Aug 2023 17:42:55 +0100 Subject: [PATCH 247/270] Run all tests on PHP 7.2 too. --- .github/workflows/integration-tests.yml | 1 + tests/_support/AcceptanceTester.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index c66fa51..f0ae948 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -40,6 +40,7 @@ jobs: - '8.1' - '8.0' - '7.4' + - '7.2' dev: - ${{ github.ref_name == 'develop' }} exclude: diff --git a/tests/_support/AcceptanceTester.php b/tests/_support/AcceptanceTester.php index f1d0d54..3889308 100644 --- a/tests/_support/AcceptanceTester.php +++ b/tests/_support/AcceptanceTester.php @@ -39,7 +39,7 @@ public function amNotUsingTheEditorForTheFirstTime() { $key, [ $value, - ], + ] ); } From bb0776d2f5dcd6eae23dc4b04e1887ab43541cff Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Mon, 21 Aug 2023 18:45:50 +0100 Subject: [PATCH 248/270] Docs. --- CONTRIBUTING.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 173df28..f2e2834 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,3 @@ -[![Build Status](https://img.shields.io/github/workflow/status/johnbillion/user-switching/Test/develop?style=flat-square)](https://github.com/johnbillion/user-switching/actions) [![](https://img.shields.io/badge/contributor-code%20of%20conduct-5e0d73.svg?style=flat-square)](https://github.com/johnbillion/user-switching/blob/develop/CODE_OF_CONDUCT.md) [![](https://img.shields.io/badge/ethical-open%20source-4baaaa.svg?style=flat-square)](#ethical-open-source) @@ -37,7 +36,7 @@ Install the PHP dependencies: ## Running the Tests -The test suite includes acceptance tests which run in a Docker container. Ensure Docker Desktop is running, then start the containers with: +The test suite includes integration and acceptance tests which run in a Docker container. Ensure Docker Desktop is running, then start the containers with: composer test:start From 504ce06aa91ff62c061593717e03da2e2c119470 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 10 Oct 2023 22:00:55 +0200 Subject: [PATCH 249/270] Make more use of Plugin Infrastructure. --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 24cefe7..0bd5146 100644 --- a/composer.json +++ b/composer.json @@ -76,7 +76,7 @@ "acceptance-tests --cli=\"language core install it_IT\" --cli=\"language plugin install user-switching it_IT\"" ], "test:destroy": [ - "COMPOSE_PROJECT_NAME=user-switching docker compose down --volumes --remove-orphans" + "tests-destroy" ], "test:integration": [ "integration-tests" @@ -89,10 +89,10 @@ "phpstan analyze --memory-limit=1024M" ], "test:start": [ - "COMPOSE_PROJECT_NAME=user-switching docker compose up -d" + "tests-start" ], "test:stop": [ - "COMPOSE_PROJECT_NAME=user-switching docker compose down" + "tests-stop" ] } } From d6b40588af0cc6169b2683a362b8e39ee1144727 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 10 Oct 2023 22:01:21 +0200 Subject: [PATCH 250/270] Always start and stop the test containers. --- composer.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 0bd5146..53cf5d6 100644 --- a/composer.json +++ b/composer.json @@ -69,8 +69,10 @@ "@composer normalize --dry-run", "@test:phpstan", "@test:phpcs", + "@test:start", "@test:integration", - "@test:acceptance" + "@test:acceptance", + "@test:stop" ], "test:acceptance": [ "acceptance-tests --cli=\"language core install it_IT\" --cli=\"language plugin install user-switching it_IT\"" From 76dbdef90a12ea53626bd3cca65ad62b8e23ce23 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 10 Oct 2023 22:02:21 +0200 Subject: [PATCH 251/270] Update to WPCS 3.0. --- composer.json | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 53cf5d6..8cb76c3 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,6 @@ "codeception/module-db": "^1.0", "codeception/module-webdriver": "^1.0", "codeception/util-universalframework": "^1.0", - "dealerdirect/phpcodesniffer-composer-installer": "0.7.2", "ergebnis/composer-normalize": "^2", "johnbillion/plugin-infrastructure": "dev-trunk", "lucatume/wp-browser": "^3.0.21", @@ -39,9 +38,8 @@ "phpstan/phpstan-phpunit": "^1.0", "roots/wordpress-core-installer": "^1.0.0", "roots/wordpress-full": "*", - "squizlabs/php_codesniffer": "3.7.1", "szepeviktor/phpstan-wordpress": "1.3.0", - "wp-coding-standards/wpcs": "2.3.0" + "wp-coding-standards/wpcs": "^3.0.0" }, "autoload-dev": { "psr-4": { @@ -51,9 +49,9 @@ "config": { "allow-plugins": { "composer/installers": true, - "dealerdirect/phpcodesniffer-composer-installer": true, "ergebnis/composer-normalize": true, - "roots/wordpress-core-installer": true + "roots/wordpress-core-installer": true, + "dealerdirect/phpcodesniffer-composer-installer": true }, "classmap-authoritative": true, "preferred-install": "dist", From 6d7f96d8d5ce5085057f92d374188ff6e33ab444 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 10 Oct 2023 22:02:42 +0200 Subject: [PATCH 252/270] Code sniffer config updates. --- composer.json | 2 +- phpcs.xml.dist | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 8cb76c3..686bc90 100644 --- a/composer.json +++ b/composer.json @@ -82,7 +82,7 @@ "integration-tests" ], "test:phpcs": [ - "phpcs -nps --colors --report-code --report-summary --report-width=80 --cache=tests/cache/phpcs.json --basepath='./' ." + "phpcs -ps --colors --report-code --report-summary --report-width=80 --basepath='./' ." ], "test:phpstan": [ "codecept build", diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 82af8d3..cbb98e4 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -1,6 +1,8 @@ + + @@ -34,27 +37,32 @@ - - + + + - + + + - + - + + + + - From acbed331452f1f4998ae76d931ba428ad68580a2 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 10 Oct 2023 22:03:12 +0200 Subject: [PATCH 253/270] Address some newly identified coding standards issues. --- user-switching.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/user-switching.php b/user-switching.php index 4d26ec5..53413e1 100644 --- a/user-switching.php +++ b/user-switching.php @@ -38,7 +38,6 @@ * Main singleton class for the User Switching plugin. */ class user_switching { - /** * The name used to identify the application during a WordPress redirect. * @@ -1195,7 +1194,6 @@ public static function get_instance() { * Private class constructor. Use `get_instance()` to get the instance. */ private function __construct() {} - } if ( ! function_exists( 'user_switching_set_olduser_cookie' ) ) { @@ -1404,16 +1402,15 @@ function switch_to_user( $user_id, $remember = false, $set_old_user = true ) { * Attaches the original user ID and session token to the new session when a user switches to another user. * * @param array $session Array of extra data. - * @param int $user_id User ID. * @return array Array of extra data. */ - $session_filter = function( array $session, $user_id ) use ( $old_user_id, $old_token ) { + $session_filter = function ( array $session ) use ( $old_user_id, $old_token ) { $session['switched_from_id'] = $old_user_id; $session['switched_from_session'] = $old_token; return $session; }; - add_filter( 'attach_session_information', $session_filter, 99, 2 ); + add_filter( 'attach_session_information', $session_filter, 99 ); wp_clear_auth_cookie(); wp_set_auth_cookie( $user_id, $remember, '', $new_token ); From 2b61aa8a6b184de7313b7af3ad492d6273e134f7 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 10 Oct 2023 23:01:37 +0200 Subject: [PATCH 254/270] Both of these are no longer needed. --- phpstan.neon.dist | 4 ---- 1 file changed, 4 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 2b99e55..853a419 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -14,10 +14,6 @@ parameters: bootstrapFiles: - tests/phpstan/stubs.php ignoreErrors: - # Uses func_get_args() - - '#^Function apply_filters invoked with [34567] parameters, 2 required\.$#' - # The 'token' element was added in WordPress 4.0 - - '#Offset ''token'' on array{username: string, expiration: string, token: string, hmac: string, scheme: string} in isset\(\) always exists and is not nullable\.#' # Covers the breaks after exits in user_switching::action_init() - message: '#^Unreachable statement#' From 787109e57e122ab47ffe7b10c4270a4f0336de79 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 10 Oct 2023 23:21:30 +0200 Subject: [PATCH 255/270] Begin tidying up and increasing the strictness of the test methods. --- tests/integration/Test.php | 25 +++++++----------- tests/integration/authenticationTest.php | 19 +++++--------- tests/integration/capabilitiesTest.php | 26 ++++++++----------- tests/integration/pluginTest.php | 7 +++-- tests/integration/sessionsTest.php | 14 +++++----- tests/integration/switchingTest.php | 33 ++++++++++-------------- tests/phpstan/stubs.php | 2 -- 7 files changed, 51 insertions(+), 75 deletions(-) diff --git a/tests/integration/Test.php b/tests/integration/Test.php index 9bd861e..35ff55d 100644 --- a/tests/integration/Test.php +++ b/tests/integration/Test.php @@ -5,21 +5,20 @@ namespace UserSwitching\Tests; abstract class Test extends \Codeception\TestCase\WPTestCase { - /** * @var array */ - protected static $users = array(); + protected static $users = []; /** * @var array */ - protected static $testers = array(); + protected static $testers = []; /** * @var array */ - protected $sessions = array(); + protected $sessions = []; /** * @return void @@ -57,10 +56,7 @@ public static function wpSetUpBeforeClass( \WP_UnitTest_Factory $factory ) { add_filter( 'user_switching_send_auth_cookies', '__return_false' ); } - /** - * @return void - */ - public function _before() { + public function _before(): void { add_action( 'set_auth_cookie', array( $this, 'action_set_auth_cookie' ), 10, 6 ); add_action( 'set_logged_in_cookie', array( $this, 'action_set_logged_in_cookie' ), 10, 6 ); add_action( 'clear_auth_cookie', array( $this, 'action_clear_auth_cookie' ) ); @@ -70,35 +66,34 @@ public function _before() { add_action( 'clear_olduser_cookie', array( $this, 'action_clear_olduser_cookie' ) ); } - public function action_set_auth_cookie( $cookie, $expire, $expiration, $user_id, $scheme, $token ) { + final public function action_set_auth_cookie( $cookie, $expire, $expiration, $user_id, $scheme, $token ): void { $_COOKIE[ SECURE_AUTH_COOKIE ] = $cookie; $_COOKIE[ AUTH_COOKIE ] = $cookie; $this->sessions[ $user_id ] = $token; } - public function action_set_logged_in_cookie( $cookie, $expire, $expiration, $user_id, $scheme, $token ) { + final public function action_set_logged_in_cookie( $cookie, $expire, $expiration, $user_id, $scheme, $token ): void { $_COOKIE[ LOGGED_IN_COOKIE ] = $cookie; } - public function action_clear_auth_cookie() { + final public function action_clear_auth_cookie(): void { unset( $_COOKIE[ LOGGED_IN_COOKIE ] ); unset( $_COOKIE[ SECURE_AUTH_COOKIE ] ); unset( $_COOKIE[ AUTH_COOKIE ] ); } - public function action_set_user_switching_cookie( $cookie, $expiration, $user_id, $scheme, $token ) { + final public function action_set_user_switching_cookie( $cookie, $expiration, $user_id, $scheme, $token ): void { $_COOKIE[ USER_SWITCHING_COOKIE ] = $cookie; $_COOKIE[ USER_SWITCHING_SECURE_COOKIE ] = $cookie; } - public function action_set_olduser_cookie( $cookie, $expiration, $user_id, $scheme, $token ) { + final public function action_set_olduser_cookie( $cookie, $expiration, $user_id, $scheme, $token ): void { $_COOKIE[ USER_SWITCHING_OLDUSER_COOKIE ] = $cookie; } - public function action_clear_olduser_cookie() { + final public function action_clear_olduser_cookie(): void { unset( $_COOKIE[ USER_SWITCHING_COOKIE ] ); unset( $_COOKIE[ USER_SWITCHING_SECURE_COOKIE ] ); unset( $_COOKIE[ USER_SWITCHING_OLDUSER_COOKIE ] ); } - } diff --git a/tests/integration/authenticationTest.php b/tests/integration/authenticationTest.php index 0c40416..9ffda76 100644 --- a/tests/integration/authenticationTest.php +++ b/tests/integration/authenticationTest.php @@ -9,9 +9,8 @@ /** * @covers \user_switching::authenticate_old_user */ -class AuthenticationTest extends Test { - - public function testValidCookiePassesAuthentication() { +final class AuthenticationTest extends Test { + public function testValidCookiePassesAuthentication(): void { $expiry = time() + 172800; $auth_cookie = wp_generate_auth_cookie( self::$testers['editor']->ID, $expiry, 'auth' ); @@ -20,14 +19,14 @@ public function testValidCookiePassesAuthentication() { self::assertFalse( user_switching::authenticate_old_user( self::$testers['admin'] ) ); } - public function testExpiredCookieDoesNotPassAuthentication() { + public function testExpiredCookieDoesNotPassAuthentication(): void { $auth_cookie = wp_generate_auth_cookie( self::$testers['editor']->ID, time() - 1000, 'auth' ); $_COOKIE[ USER_SWITCHING_COOKIE ] = json_encode( array( $auth_cookie ) ); self::assertFalse( user_switching::authenticate_old_user( self::$testers['editor'] ) ); self::assertFalse( user_switching::authenticate_old_user( self::$testers['admin'] ) ); } - public function testValidCookieWithIncorrectSchemeDoesNotPassAuthentication() { + public function testValidCookieWithIncorrectSchemeDoesNotPassAuthentication(): void { $expiry = time() + 172800; $logged_in_cookie = wp_generate_auth_cookie( self::$testers['editor']->ID, $expiry, 'logged_in' ); @@ -40,16 +39,13 @@ public function testValidCookieWithIncorrectSchemeDoesNotPassAuthentication() { self::assertFalse( user_switching::authenticate_old_user( self::$testers['admin'] ) ); } - public function testMalformedCookieDoesNotPassAuthentication() { + public function testMalformedCookieDoesNotPassAuthentication(): void { $_COOKIE[ USER_SWITCHING_COOKIE ] = 'hello'; self::assertFalse( user_switching::authenticate_old_user( self::$testers['editor'] ) ); self::assertFalse( user_switching::authenticate_old_user( self::$testers['admin'] ) ); } - /** - * @testdox A non-JSON encoded cookie does not pass authentication - */ - public function testANonJsonEncodedCookieDoesNotPassAuthentication() { + public function testANonJsonEncodedCookieDoesNotPassAuthentication(): void { $expiry = time() + 172800; $auth_cookie = wp_generate_auth_cookie( self::$testers['editor']->ID, $expiry, 'auth' ); @@ -58,10 +54,9 @@ public function testANonJsonEncodedCookieDoesNotPassAuthentication() { self::assertFalse( user_switching::authenticate_old_user( self::$testers['admin'] ) ); } - public function testNoCookieDoesNotPassAuthentication() { + public function testNoCookieDoesNotPassAuthentication(): void { unset( $_COOKIE[ USER_SWITCHING_COOKIE ] ); self::assertFalse( user_switching::authenticate_old_user( self::$testers['editor'] ) ); self::assertFalse( user_switching::authenticate_old_user( self::$testers['admin'] ) ); } - } diff --git a/tests/integration/capabilitiesTest.php b/tests/integration/capabilitiesTest.php index e49f282..1223985 100644 --- a/tests/integration/capabilitiesTest.php +++ b/tests/integration/capabilitiesTest.php @@ -8,12 +8,11 @@ * @covers \user_switching::filter_user_has_cap * @covers \user_switching::filter_map_meta_cap */ -class CapabilitiesTest extends Test { - +final class CapabilitiesTest extends Test { /** * @return array> */ - public function data_roles() { + public function data_roles(): array { $roles = [ 'admin' => [ 'admin', @@ -51,7 +50,7 @@ public function data_roles() { return $roles; } - public function testAllRolesAreTested() { + public function testAllRolesAreTested(): void { $tested_roles = array_column( $this->data_roles(), 0 ); self::assertSame( array_keys( self::$testers ), $tested_roles ); @@ -60,9 +59,8 @@ public function testAllRolesAreTested() { /** * @dataProvider data_roles - * @testdox User with role of $role can or cannot switch according to role */ - public function testUserCanOrCannotSwitchAccordingToRole( $role, $can_switch ) { + public function testUserCanOrCannotSwitchAccordingToRole( string $role, bool $can_switch ): void { foreach ( self::$users as $user_role => $user ) { if ( self::$testers[ $role ]->ID === $user->ID ) { # No user can switch to themselves: @@ -80,7 +78,7 @@ public function testUserCanOrCannotSwitchAccordingToRole( $role, $can_switch ) { self::assertSame( $can_switch, user_can( self::$testers[ $role ]->ID, 'switch_off' ) ); } - public function testAbilityToSwitchUsersCanBeGrantedToUser() { + public function testAbilityToSwitchUsersCanBeGrantedToUser(): void { # Editors cannot switch to other users: $can_already_switch = user_can( self::$testers['editor']->ID, 'switch_to_user', self::$users['admin']->ID ); @@ -100,7 +98,7 @@ public function testAbilityToSwitchUsersCanBeGrantedToUser() { self::assertTrue( $can_switch_off ); } - public function testAbilityToSwitchUsersCanBeGrantedToRole() { + public function testAbilityToSwitchUsersCanBeGrantedToRole(): void { # Editors cannot switch to other users: $can_already_switch = user_can( self::$testers['editor']->ID, 'switch_to_user', self::$users['admin']->ID ); @@ -126,7 +124,7 @@ public function testAbilityToSwitchUsersCanBeGrantedToRole() { /** * @group ms-excluded */ - public function testAbilityToSwitchUsersCanBeDeniedFromUser() { + public function testAbilityToSwitchUsersCanBeDeniedFromUser(): void { # Admins can switch to other users: $can_already_switch = user_can( self::$testers['admin']->ID, 'switch_to_user', self::$users['author']->ID ); @@ -149,7 +147,7 @@ public function testAbilityToSwitchUsersCanBeDeniedFromUser() { /** * @group ms-excluded */ - public function testAbilityToSwitchUsersCanBeDeniedFromRole() { + public function testAbilityToSwitchUsersCanBeDeniedFromRole(): void { # Admins can switch to other users: $can_already_switch = user_can( self::$testers['admin']->ID, 'switch_to_user', self::$users['author']->ID ); @@ -176,7 +174,7 @@ public function testAbilityToSwitchUsersCanBeDeniedFromRole() { * @group multisite * @group ms-required */ - public function testAbilityToSwitchUsersCanBeGrantedToAdministratorRoleOnMultisite() { + public function testAbilityToSwitchUsersCanBeGrantedToAdministratorRoleOnMultisite(): void { # Admins on Multisite cannot switch to other users: $can_already_switch = user_can( self::$testers['admin']->ID, 'switch_to_user', self::$users['author']->ID ); @@ -203,7 +201,7 @@ public function testAbilityToSwitchUsersCanBeGrantedToAdministratorRoleOnMultisi * @group multisite * @group ms-required */ - public function testAbilityToSwitchUsersCanBeGrantedToAdministratorUserOnMultisite() { + public function testAbilityToSwitchUsersCanBeGrantedToAdministratorUserOnMultisite(): void { # Admins on Multisite cannot switch to other users: $can_already_switch = user_can( self::$testers['admin']->ID, 'switch_to_user', self::$users['author']->ID ); @@ -225,10 +223,8 @@ public function testAbilityToSwitchUsersCanBeGrantedToAdministratorUserOnMultisi /** * @dataProvider data_roles - * @testdox User with role of $role cannot switch to no user */ - public function testSwitchingToNoUserIsNotAllowed( $role ) { + public function testSwitchingToNoUserIsNotAllowed( string $role ): void { self::assertFalse( user_can( self::$testers[ $role ]->ID, 'switch_to_user', 0 ) ); } - } diff --git a/tests/integration/pluginTest.php b/tests/integration/pluginTest.php index fb598e4..9463a42 100644 --- a/tests/integration/pluginTest.php +++ b/tests/integration/pluginTest.php @@ -4,13 +4,13 @@ namespace UserSwitching\Tests; -class PluginTest extends Test { +final class PluginTest extends Test { /** * @var ?array */ private $readme_data; - public function testStableTagMatchesVersion() { + public function testStableTagMatchesVersion(): void { $readme_data = $this->get_readme(); if ( null === $readme_data ) { self::fail( 'There is no readme file' ); @@ -24,7 +24,7 @@ public function testStableTagMatchesVersion() { /** * @return ?array */ - private function get_readme() { + private function get_readme(): ?array { if ( ! isset( $this->readme_data ) ) { $file = dirname( dirname( __DIR__ ) ) . '/readme.md'; @@ -49,5 +49,4 @@ private function get_readme() { return $this->readme_data; } - } diff --git a/tests/integration/sessionsTest.php b/tests/integration/sessionsTest.php index e04babd..ebc1ae4 100644 --- a/tests/integration/sessionsTest.php +++ b/tests/integration/sessionsTest.php @@ -7,12 +7,11 @@ use user_switching; use WP_Session_Tokens; -class SessionsTest extends Test { - +final class SessionsTest extends Test { /** * @covers \switch_to_user */ - public function testExtraSessionsAreNotCreatedForUsersWhenSwitching() { + public function testExtraSessionsAreNotCreatedForUsersWhenSwitching(): void { if ( is_multisite() ) { $admin = self::$testers['super']; } else { @@ -49,7 +48,7 @@ public function testExtraSessionsAreNotCreatedForUsersWhenSwitching() { /** * @covers \switch_off_user */ - public function testExtraSessionsAreNotCreatedForUserWhenSwitchingOff() { + public function testExtraSessionsAreNotCreatedForUserWhenSwitchingOff(): void { if ( is_multisite() ) { $admin = self::$testers['super']; } else { @@ -79,7 +78,7 @@ public function testExtraSessionsAreNotCreatedForUserWhenSwitchingOff() { * @covers \switch_to_user * @covers \switch_off_user */ - public function testPreviousSessionForUserIsReusedWhenSwitchingBack() { + public function testPreviousSessionForUserIsReusedWhenSwitchingBack(): void { if ( is_multisite() ) { $admin = self::$testers['super']; } else { @@ -132,7 +131,7 @@ public function testPreviousSessionForUserIsReusedWhenSwitchingBack() { /** * @covers \switch_to_user */ - public function testExpiredSessionPreventsUserFromSwitchingBack() { + public function testExpiredSessionPreventsUserFromSwitchingBack(): void { if ( is_multisite() ) { $admin = self::$testers['super']; } else { @@ -188,7 +187,7 @@ public function testExpiredSessionPreventsUserFromSwitchingBack() { * @covers \switch_to_user * @covers \switch_off_user */ - public function testSessionTokensAreCorrectlyReusedWhenSwitching() { + public function testSessionTokensAreCorrectlyReusedWhenSwitching(): void { if ( is_multisite() ) { $admin = self::$testers['super']; } else { @@ -261,5 +260,4 @@ public function testSessionTokensAreCorrectlyReusedWhenSwitching() { self::assertCount( 1, $admin_manager->get_all() ); self::assertNotNull( $admin_manager->get( $admin_token ) ); } - } diff --git a/tests/integration/switchingTest.php b/tests/integration/switchingTest.php index 2beb005..1b15525 100644 --- a/tests/integration/switchingTest.php +++ b/tests/integration/switchingTest.php @@ -6,29 +6,28 @@ use user_switching; -class SwitchingTest extends Test { - +final class SwitchingTest extends Test { /** * @var int|false */ - public $test_switching_user_id; + private $test_switching_user_id; /** * @var int|false */ - public $test_switching_old_user_id; + private $test_switching_old_user_id; /** * @var int */ - public $test_switching_auth_cookie_user_id; + private $test_switching_auth_cookie_user_id; /** * @var bool */ - public $test_switching_auth_cookie_remember; + private $test_switching_auth_cookie_remember; - public function _before() { + public function _before(): void { parent::_before(); add_action( 'switch_to_user', array( $this, '_action_switch_user' ), 10, 2 ); @@ -40,7 +39,7 @@ public function _before() { /** * @covers \switch_to_user */ - public function testSwitchUserAndBack() { + public function testSwitchUserAndBack(): void { if ( is_multisite() ) { $admin = self::$testers['super']; } else { @@ -145,7 +144,7 @@ public function testSwitchUserAndBack() { * @covers \switch_to_user * @covers \switch_off_user */ - public function testSwitchOffAndBack() { + public function testSwitchOffAndBack(): void { if ( is_multisite() ) { $admin = self::$testers['super']; } else { @@ -200,7 +199,7 @@ public function testSwitchOffAndBack() { /** * @covers \switch_to_user */ - public function testSwitchToNonExistentUserFails() { + public function testSwitchToNonExistentUserFails(): void { // Switch user $user = switch_to_user( 0 ); @@ -208,10 +207,9 @@ public function testSwitchToNonExistentUserFails() { } /** - * @testdox Current URL is detected correctly * @covers \user_switching::current_url */ - public function testCurrentUrl() { + public function testCurrentUrl(): void { $url = add_query_arg( 'foo', 'bar', home_url( 'baz' ) ); $this->go_to( $url ); self::assertSame( user_switching::current_url(), $url ); @@ -221,23 +219,20 @@ public function testCurrentUrl() { * @param int $user_id * @param int|false $old_user_id */ - public function _action_switch_user( $user_id, $old_user_id ) { + public function _action_switch_user( $user_id, $old_user_id ): void { $this->test_switching_user_id = $user_id; $this->test_switching_old_user_id = $old_user_id; } - public function _action_switch_off( $old_user_id ) { + public function _action_switch_off( int $old_user_id ): void { $this->test_switching_user_id = false; $this->test_switching_old_user_id = $old_user_id; } - /** - * @return int - */ - public function _filter_auth_cookie_expiration( $length, $user_id, $remember ) { + public function _filter_auth_cookie_expiration( int $length, int $user_id, bool $remember ): int { $this->test_switching_auth_cookie_user_id = $user_id; $this->test_switching_auth_cookie_remember = $remember; + return $length; } - } diff --git a/tests/phpstan/stubs.php b/tests/phpstan/stubs.php index 3a58cd1..02c4188 100644 --- a/tests/phpstan/stubs.php +++ b/tests/phpstan/stubs.php @@ -41,7 +41,6 @@ function bp_get_button( array $args ) {} function buddypress() {} class BuddyPress { - /** * @var array */ @@ -59,7 +58,6 @@ function bbp_get_user_id() {} function bbp_get_user_profile_url( int $user_id ) {} class WooCommerce { - /** * @var \WC_Session */ From 414afa444224c24d89fc49fd7192b2b8537daf8b Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 10 Oct 2023 23:21:48 +0200 Subject: [PATCH 256/270] Scan the test classes with PHPStan. --- phpstan.neon.dist | 3 +++ 1 file changed, 3 insertions(+) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 853a419..a0ee43d 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -6,8 +6,11 @@ parameters: level: 9 paths: - user-switching.php + - tests/acceptance + - tests/integration scanDirectories: - tests/_support/ + - vendor/lucatume/wp-browser/src/includes/factory/ excludePaths: analyse: - tests/integration/Supports/ From 4e2107522d71a7a0bd43f9edcf61735e28da7442 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 10 Oct 2023 23:30:48 +0200 Subject: [PATCH 257/270] More type strictness in the tests. --- tests/acceptance/SwitchFromEnglishCest.php | 8 ++++---- tests/acceptance/SwitchOffCest.php | 22 +++++++++++----------- tests/acceptance/SwitchToEnglishCest.php | 8 ++++---- tests/acceptance/SwitchUserCest.php | 10 +++++----- tests/integration/Test.php | 4 +--- tests/integration/authenticationTest.php | 4 +--- tests/integration/capabilitiesTest.php | 4 +--- tests/integration/pluginTest.php | 4 +--- tests/integration/sessionsTest.php | 4 +--- tests/integration/switchingTest.php | 4 +--- 10 files changed, 30 insertions(+), 42 deletions(-) diff --git a/tests/acceptance/SwitchFromEnglishCest.php b/tests/acceptance/SwitchFromEnglishCest.php index 7edbd76..b31e75f 100644 --- a/tests/acceptance/SwitchFromEnglishCest.php +++ b/tests/acceptance/SwitchFromEnglishCest.php @@ -1,10 +1,10 @@ -comment( 'As an administrator of a site which uses more than one language' ); $I->comment( 'I need to be able to switch to user accounts that use a different language' ); $I->comment( 'And see the output of User Switching in my original language' ); @@ -17,7 +17,7 @@ public function _before( AcceptanceTester $I ) { ] ); } - public function SwitchFromEnglishAdminToItalianAuthorAndBack( AcceptanceTester $I ) { + public function SwitchFromEnglishAdminToItalianAuthorAndBack( AcceptanceTester $I ): void { $I->loginAsAdmin(); $I->switchToUser( 'autore' ); $I->canSeeThePageInLanguage( 'it-IT' ); diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index 4228fc8..d738506 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -1,16 +1,16 @@ -comment( 'As an administrator' ); $I->comment( 'I need to be able to switch off' ); $I->comment( 'In order to view the site without logging out completely' ); } - public function SwitchOffFromDashboardAndBackFromFrontEnd( AcceptanceTester $I ) { + public function SwitchOffFromDashboardAndBackFromFrontEnd( AcceptanceTester $I ): void { $I->loginAsAdmin(); $I->amOnAdminPage( '/' ); $I->switchOff(); @@ -22,7 +22,7 @@ public function SwitchOffFromDashboardAndBackFromFrontEnd( AcceptanceTester $I ) $I->amLoggedInAs( 'admin' ); } - public function SwitchOffFromDashboardAndBackFromLoginScreen( AcceptanceTester $I ) { + public function SwitchOffFromDashboardAndBackFromLoginScreen( AcceptanceTester $I ): void { $I->loginAsAdmin(); $I->amOnAdminPage( '/' ); $I->switchOff(); @@ -36,7 +36,7 @@ public function SwitchOffFromDashboardAndBackFromLoginScreen( AcceptanceTester $ $I->amLoggedInAs( 'admin' ); } - public function SwitchOffFromPublishedPostEditingScreen( AcceptanceTester $I ) { + public function SwitchOffFromPublishedPostEditingScreen( AcceptanceTester $I ): void { $I->loginAsAdmin(); $id = $I->havePostInDatabase( [ 'post_status' => 'publish', @@ -49,7 +49,7 @@ public function SwitchOffFromPublishedPostEditingScreen( AcceptanceTester $I ) { $I->amLoggedOut(); } - public function SwitchOffFromDraftPostEditingScreen( AcceptanceTester $I ) { + public function SwitchOffFromDraftPostEditingScreen( AcceptanceTester $I ): void { $I->loginAsAdmin(); $id = $I->havePostInDatabase( [ 'post_status' => 'draft', @@ -62,7 +62,7 @@ public function SwitchOffFromDraftPostEditingScreen( AcceptanceTester $I ) { $I->amLoggedOut(); } - public function SwitchOffFromTermEditingScreen( AcceptanceTester $I ) { + public function SwitchOffFromTermEditingScreen( AcceptanceTester $I ): void { $I->loginAsAdmin(); $term = $I->haveTermInDatabase( 'hello', 'category' ); $I->amOnAdminPage( '/term.php?taxonomy=category&tag_ID=' . $term[0] ); @@ -79,7 +79,7 @@ public function SwitchOffFromTermEditingScreen( AcceptanceTester $I ) { $I->amLoggedOut(); } - public function SwitchOffFromUserEditingScreen( AcceptanceTester $I ) { + public function SwitchOffFromUserEditingScreen( AcceptanceTester $I ): void { $I->loginAsAdmin(); $id = $I->haveUserInDatabase( 'example', 'editor' ); // https://github.com/lucatume/wp-browser/pull/586 @@ -90,7 +90,7 @@ public function SwitchOffFromUserEditingScreen( AcceptanceTester $I ) { $I->amLoggedOut(); } - public function SwitchOffFromApprovedCommentEditingScreen( AcceptanceTester $I ) { + public function SwitchOffFromApprovedCommentEditingScreen( AcceptanceTester $I ): void { $I->loginAsAdmin(); $postId = $I->havePostInDatabase( [ 'post_status' => 'publish', @@ -105,7 +105,7 @@ public function SwitchOffFromApprovedCommentEditingScreen( AcceptanceTester $I ) $I->amLoggedOut(); } - public function SwitchOffFromUnapprovedCommentEditingScreen( AcceptanceTester $I ) { + public function SwitchOffFromUnapprovedCommentEditingScreen( AcceptanceTester $I ): void { $I->loginAsAdmin(); $postId = $I->havePostInDatabase( [ 'post_status' => 'publish', diff --git a/tests/acceptance/SwitchToEnglishCest.php b/tests/acceptance/SwitchToEnglishCest.php index 947bbc2..47d11d4 100644 --- a/tests/acceptance/SwitchToEnglishCest.php +++ b/tests/acceptance/SwitchToEnglishCest.php @@ -1,10 +1,10 @@ -comment( 'As an administrator of a site which uses more than one language' ); $I->comment( 'I need to be able to switch between users' ); $I->comment( 'And see the output of User Switching in my original language' ); @@ -20,7 +20,7 @@ public function _before( AcceptanceTester $I ) { ] ); } - public function SwitchFromItalianAdminToEnglishAuthorAndBack( AcceptanceTester $I ) { + public function SwitchFromItalianAdminToEnglishAuthorAndBack( AcceptanceTester $I ): void { $I->loginAs( 'admin_it', 'admin_it' ); $I->switchToUser( 'author_en' ); $I->canSeeThePageInLanguage( 'en-US' ); diff --git a/tests/acceptance/SwitchUserCest.php b/tests/acceptance/SwitchUserCest.php index 8cd77f7..e4eeacb 100644 --- a/tests/acceptance/SwitchUserCest.php +++ b/tests/acceptance/SwitchUserCest.php @@ -1,16 +1,16 @@ -comment( 'As an administrator' ); $I->comment( 'I need to be able to switch between users' ); $I->comment( 'In order to access different user accounts' ); } - public function SwitchToEditorThenBackFromFrontEnd( AcceptanceTester $I ) { + public function SwitchToEditorThenBackFromFrontEnd( AcceptanceTester $I ): void { $I->loginAsAdmin(); $I->haveUserInDatabase( 'editor', 'editor' ); @@ -25,7 +25,7 @@ public function SwitchToEditorThenBackFromFrontEnd( AcceptanceTester $I ) { $I->amLoggedInAs( 'admin' ); } - public function SwitchToEditorThenBackFromAdminArea( AcceptanceTester $I ) { + public function SwitchToEditorThenBackFromAdminArea( AcceptanceTester $I ): void { $I->loginAsAdmin(); $I->haveUserInDatabase( 'editor', 'editor' ); diff --git a/tests/integration/Test.php b/tests/integration/Test.php index 35ff55d..6d95527 100644 --- a/tests/integration/Test.php +++ b/tests/integration/Test.php @@ -1,6 +1,4 @@ - Date: Tue, 10 Oct 2023 23:31:03 +0200 Subject: [PATCH 258/270] More parameter types. --- tests/integration/Test.php | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/integration/Test.php b/tests/integration/Test.php index 6d95527..83a3b28 100644 --- a/tests/integration/Test.php +++ b/tests/integration/Test.php @@ -56,21 +56,28 @@ public static function wpSetUpBeforeClass( \WP_UnitTest_Factory $factory ) { public function _before(): void { add_action( 'set_auth_cookie', array( $this, 'action_set_auth_cookie' ), 10, 6 ); - add_action( 'set_logged_in_cookie', array( $this, 'action_set_logged_in_cookie' ), 10, 6 ); + add_action( 'set_logged_in_cookie', array( $this, 'action_set_logged_in_cookie' ), 10 ); add_action( 'clear_auth_cookie', array( $this, 'action_clear_auth_cookie' ) ); - add_action( 'set_user_switching_cookie', array( $this, 'action_set_user_switching_cookie' ), 10, 5 ); - add_action( 'set_olduser_cookie', array( $this, 'action_set_olduser_cookie' ), 10, 5 ); + add_action( 'set_user_switching_cookie', array( $this, 'action_set_user_switching_cookie' ), 10 ); + add_action( 'set_olduser_cookie', array( $this, 'action_set_olduser_cookie' ), 10 ); add_action( 'clear_olduser_cookie', array( $this, 'action_clear_olduser_cookie' ) ); } - final public function action_set_auth_cookie( $cookie, $expire, $expiration, $user_id, $scheme, $token ): void { + final public function action_set_auth_cookie( + string $cookie, + int $expire, + int $expiration, + int $user_id, + string $scheme, + string $token, + ): void { $_COOKIE[ SECURE_AUTH_COOKIE ] = $cookie; $_COOKIE[ AUTH_COOKIE ] = $cookie; $this->sessions[ $user_id ] = $token; } - final public function action_set_logged_in_cookie( $cookie, $expire, $expiration, $user_id, $scheme, $token ): void { + final public function action_set_logged_in_cookie( string $cookie ): void { $_COOKIE[ LOGGED_IN_COOKIE ] = $cookie; } @@ -80,12 +87,12 @@ final public function action_clear_auth_cookie(): void { unset( $_COOKIE[ AUTH_COOKIE ] ); } - final public function action_set_user_switching_cookie( $cookie, $expiration, $user_id, $scheme, $token ): void { + final public function action_set_user_switching_cookie( string $cookie ): void { $_COOKIE[ USER_SWITCHING_COOKIE ] = $cookie; $_COOKIE[ USER_SWITCHING_SECURE_COOKIE ] = $cookie; } - final public function action_set_olduser_cookie( $cookie, $expiration, $user_id, $scheme, $token ): void { + final public function action_set_olduser_cookie( string $cookie ): void { $_COOKIE[ USER_SWITCHING_OLDUSER_COOKIE ] = $cookie; } From 34fde35cd1d7ece4696e5014a1ccba07c38852d2 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 10 Oct 2023 23:35:23 +0200 Subject: [PATCH 259/270] These can all be namespaced. --- tests/acceptance/SwitchFromEnglishCest.php | 8 +++++--- tests/acceptance/SwitchOffCest.php | 22 ++++++++++++---------- tests/acceptance/SwitchToEnglishCest.php | 8 +++++--- tests/acceptance/SwitchUserCest.php | 10 ++++++---- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/tests/acceptance/SwitchFromEnglishCest.php b/tests/acceptance/SwitchFromEnglishCest.php index b31e75f..48501cf 100644 --- a/tests/acceptance/SwitchFromEnglishCest.php +++ b/tests/acceptance/SwitchFromEnglishCest.php @@ -1,10 +1,12 @@ comment( 'As an administrator of a site which uses more than one language' ); $I->comment( 'I need to be able to switch to user accounts that use a different language' ); $I->comment( 'And see the output of User Switching in my original language' ); @@ -17,7 +19,7 @@ public function _before( AcceptanceTester $I ): void { ] ); } - public function SwitchFromEnglishAdminToItalianAuthorAndBack( AcceptanceTester $I ): void { + public function SwitchFromEnglishAdminToItalianAuthorAndBack( \AcceptanceTester $I ): void { $I->loginAsAdmin(); $I->switchToUser( 'autore' ); $I->canSeeThePageInLanguage( 'it-IT' ); diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index d738506..374f4bb 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -1,16 +1,18 @@ comment( 'As an administrator' ); $I->comment( 'I need to be able to switch off' ); $I->comment( 'In order to view the site without logging out completely' ); } - public function SwitchOffFromDashboardAndBackFromFrontEnd( AcceptanceTester $I ): void { + public function SwitchOffFromDashboardAndBackFromFrontEnd( \AcceptanceTester $I ): void { $I->loginAsAdmin(); $I->amOnAdminPage( '/' ); $I->switchOff(); @@ -22,7 +24,7 @@ public function SwitchOffFromDashboardAndBackFromFrontEnd( AcceptanceTester $I ) $I->amLoggedInAs( 'admin' ); } - public function SwitchOffFromDashboardAndBackFromLoginScreen( AcceptanceTester $I ): void { + public function SwitchOffFromDashboardAndBackFromLoginScreen( \AcceptanceTester $I ): void { $I->loginAsAdmin(); $I->amOnAdminPage( '/' ); $I->switchOff(); @@ -36,7 +38,7 @@ public function SwitchOffFromDashboardAndBackFromLoginScreen( AcceptanceTester $ $I->amLoggedInAs( 'admin' ); } - public function SwitchOffFromPublishedPostEditingScreen( AcceptanceTester $I ): void { + public function SwitchOffFromPublishedPostEditingScreen( \AcceptanceTester $I ): void { $I->loginAsAdmin(); $id = $I->havePostInDatabase( [ 'post_status' => 'publish', @@ -49,7 +51,7 @@ public function SwitchOffFromPublishedPostEditingScreen( AcceptanceTester $I ): $I->amLoggedOut(); } - public function SwitchOffFromDraftPostEditingScreen( AcceptanceTester $I ): void { + public function SwitchOffFromDraftPostEditingScreen( \AcceptanceTester $I ): void { $I->loginAsAdmin(); $id = $I->havePostInDatabase( [ 'post_status' => 'draft', @@ -62,7 +64,7 @@ public function SwitchOffFromDraftPostEditingScreen( AcceptanceTester $I ): void $I->amLoggedOut(); } - public function SwitchOffFromTermEditingScreen( AcceptanceTester $I ): void { + public function SwitchOffFromTermEditingScreen( \AcceptanceTester $I ): void { $I->loginAsAdmin(); $term = $I->haveTermInDatabase( 'hello', 'category' ); $I->amOnAdminPage( '/term.php?taxonomy=category&tag_ID=' . $term[0] ); @@ -79,7 +81,7 @@ public function SwitchOffFromTermEditingScreen( AcceptanceTester $I ): void { $I->amLoggedOut(); } - public function SwitchOffFromUserEditingScreen( AcceptanceTester $I ): void { + public function SwitchOffFromUserEditingScreen( \AcceptanceTester $I ): void { $I->loginAsAdmin(); $id = $I->haveUserInDatabase( 'example', 'editor' ); // https://github.com/lucatume/wp-browser/pull/586 @@ -90,7 +92,7 @@ public function SwitchOffFromUserEditingScreen( AcceptanceTester $I ): void { $I->amLoggedOut(); } - public function SwitchOffFromApprovedCommentEditingScreen( AcceptanceTester $I ): void { + public function SwitchOffFromApprovedCommentEditingScreen( \AcceptanceTester $I ): void { $I->loginAsAdmin(); $postId = $I->havePostInDatabase( [ 'post_status' => 'publish', @@ -105,7 +107,7 @@ public function SwitchOffFromApprovedCommentEditingScreen( AcceptanceTester $I ) $I->amLoggedOut(); } - public function SwitchOffFromUnapprovedCommentEditingScreen( AcceptanceTester $I ): void { + public function SwitchOffFromUnapprovedCommentEditingScreen( \AcceptanceTester $I ): void { $I->loginAsAdmin(); $postId = $I->havePostInDatabase( [ 'post_status' => 'publish', diff --git a/tests/acceptance/SwitchToEnglishCest.php b/tests/acceptance/SwitchToEnglishCest.php index 47d11d4..3db08e0 100644 --- a/tests/acceptance/SwitchToEnglishCest.php +++ b/tests/acceptance/SwitchToEnglishCest.php @@ -1,10 +1,12 @@ comment( 'As an administrator of a site which uses more than one language' ); $I->comment( 'I need to be able to switch between users' ); $I->comment( 'And see the output of User Switching in my original language' ); @@ -20,7 +22,7 @@ public function _before( AcceptanceTester $I ): void { ] ); } - public function SwitchFromItalianAdminToEnglishAuthorAndBack( AcceptanceTester $I ): void { + public function SwitchFromItalianAdminToEnglishAuthorAndBack( \AcceptanceTester $I ): void { $I->loginAs( 'admin_it', 'admin_it' ); $I->switchToUser( 'author_en' ); $I->canSeeThePageInLanguage( 'en-US' ); diff --git a/tests/acceptance/SwitchUserCest.php b/tests/acceptance/SwitchUserCest.php index e4eeacb..ecd39ce 100644 --- a/tests/acceptance/SwitchUserCest.php +++ b/tests/acceptance/SwitchUserCest.php @@ -1,16 +1,18 @@ comment( 'As an administrator' ); $I->comment( 'I need to be able to switch between users' ); $I->comment( 'In order to access different user accounts' ); } - public function SwitchToEditorThenBackFromFrontEnd( AcceptanceTester $I ): void { + public function SwitchToEditorThenBackFromFrontEnd( \AcceptanceTester $I ): void { $I->loginAsAdmin(); $I->haveUserInDatabase( 'editor', 'editor' ); @@ -25,7 +27,7 @@ public function SwitchToEditorThenBackFromFrontEnd( AcceptanceTester $I ): void $I->amLoggedInAs( 'admin' ); } - public function SwitchToEditorThenBackFromAdminArea( AcceptanceTester $I ): void { + public function SwitchToEditorThenBackFromAdminArea( \AcceptanceTester $I ): void { $I->loginAsAdmin(); $I->haveUserInDatabase( 'editor', 'editor' ); From e46d810782e226a20c13b6a33665f5cc21daa606 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 10 Oct 2023 23:39:23 +0200 Subject: [PATCH 260/270] Trailing commas in argument lists are only supported in PHP 8. --- tests/integration/Test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/Test.php b/tests/integration/Test.php index 83a3b28..60c0fa8 100644 --- a/tests/integration/Test.php +++ b/tests/integration/Test.php @@ -70,7 +70,7 @@ final public function action_set_auth_cookie( int $expiration, int $user_id, string $scheme, - string $token, + string $token ): void { $_COOKIE[ SECURE_AUTH_COOKIE ] = $cookie; $_COOKIE[ AUTH_COOKIE ] = $cookie; From 3dd1b5845508fdb2f8cfd5e952dbd4366af66623 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 10 Oct 2023 23:48:20 +0200 Subject: [PATCH 261/270] None of this is needed now. --- phpcs.xml.dist | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/phpcs.xml.dist b/phpcs.xml.dist index cbb98e4..25b4825 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -5,18 +5,8 @@ - - - - */.github/* - */build/* - */features/* - */node_modules/* - */tests/* - */vendor/* + /tests/* + /vendor/* From 642d8cecfa0e9035be13e802182ac1dcb283d752 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 16 Nov 2023 20:45:26 +0000 Subject: [PATCH 262/270] Too many people still think it's acceptable to demand personal support via email. --- CODE_OF_CONDUCT.md | 2 +- user-switching.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index dff8121..5597c7e 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -61,7 +61,7 @@ representative at an online or offline event. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at -john@johnblackbourn.com. +https://johnblackbourn.com/about/ . All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the diff --git a/user-switching.php b/user-switching.php index 53413e1..a682e3a 100644 --- a/user-switching.php +++ b/user-switching.php @@ -4,7 +4,7 @@ * * @package user-switching * @link https://github.com/johnbillion/user-switching - * @author John Blackbourn + * @author John Blackbourn * @copyright 2009-2023 John Blackbourn * @license GPL v2 or later * From d2aed7815efb150ceb8ed355682b494852c4e2c9 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 16 Nov 2023 21:18:33 +0000 Subject: [PATCH 263/270] Bump the PHP and WordPress supported versions. --- .github/workflows/acceptance-tests.yml | 1 - .github/workflows/integration-tests.yml | 1 - composer.json | 2 +- phpcs.xml.dist | 4 ++-- readme.md | 4 ++-- tests/acceptance/SwitchOffCest.php | 10 +--------- user-switching.php | 22 ++++++++++++---------- 7 files changed, 18 insertions(+), 26 deletions(-) diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml index a6ca443..1c61465 100644 --- a/.github/workflows/acceptance-tests.yml +++ b/.github/workflows/acceptance-tests.yml @@ -38,7 +38,6 @@ jobs: - '8.1' - '8.0' - '7.4' - - '7.2' dev: - ${{ github.ref_name == 'develop' }} exclude: diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index f0ae948..c66fa51 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -40,7 +40,6 @@ jobs: - '8.1' - '8.0' - '7.4' - - '7.2' dev: - ${{ github.ref_name == 'develop' }} exclude: diff --git a/composer.json b/composer.json index 686bc90..86d6c64 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ } ], "require": { - "php": ">=7.2", + "php": ">=7.4", "composer/installers": "^1.0 || ^2.0" }, "require-dev": { diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 25b4825..47a202f 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -2,8 +2,8 @@ - - + + /tests/* /vendor/* diff --git a/readme.md b/readme.md index e661263..eb68704 100644 --- a/readme.md +++ b/readme.md @@ -1,9 +1,7 @@ # User Switching Stable tag: 1.7.0 -Requires at least: 5.1 Tested up to: 6.3 -Requires PHP: 7.2 License: GPL v2 or later Tags: users, user switching, fast user switching, multisite, woocommerce, buddypress, bbpress Contributors: johnbillion @@ -30,6 +28,8 @@ This plugin allows you to quickly swap between user accounts in WordPress at the * Compatible with most two-factor authentication solutions (see the [FAQ](https://wordpress.org/plugins/user-switching/faq/) for more info). * Approved for use on enterprise-grade WordPress platforms such as Altis and WordPress VIP. +Note: User Switching supports versions of WordPress up to three years old, and PHP version 7.4 or higher. + ### Security * Only users with the ability to edit other users can switch user accounts. By default this is only Administrators on single site installations, and Super Admins on Multisite installations. diff --git a/tests/acceptance/SwitchOffCest.php b/tests/acceptance/SwitchOffCest.php index 374f4bb..fa2bcac 100644 --- a/tests/acceptance/SwitchOffCest.php +++ b/tests/acceptance/SwitchOffCest.php @@ -69,15 +69,7 @@ public function SwitchOffFromTermEditingScreen( \AcceptanceTester $I ): void { $term = $I->haveTermInDatabase( 'hello', 'category' ); $I->amOnAdminPage( '/term.php?taxonomy=category&tag_ID=' . $term[0] ); $I->switchOff(); - - try { - // WordPress >= 5.1: - $I->seeCurrentUrlEquals( '/category/hello/?switched_off=true' ); - } catch ( \PHPUnit\Framework\ExpectationFailedException $e ) { - // WordPress < 5.1: - $I->seeCurrentUrlEquals( '?switched_off=true' ); - } - + $I->seeCurrentUrlEquals( '/category/hello/?switched_off=true' ); $I->amLoggedOut(); } diff --git a/user-switching.php b/user-switching.php index a682e3a..3a1403e 100644 --- a/user-switching.php +++ b/user-switching.php @@ -8,16 +8,18 @@ * @copyright 2009-2023 John Blackbourn * @license GPL v2 or later * - * Plugin Name: User Switching - * Description: Instant switching between user accounts in WordPress - * Version: 1.7.0 - * Plugin URI: https://wordpress.org/plugins/user-switching/ - * Author: John Blackbourn & contributors - * Author URI: https://github.com/johnbillion/user-switching/graphs/contributors - * Text Domain: user-switching - * Domain Path: /languages/ - * Network: true - * Requires PHP: 7.2 + * Plugin Name: User Switching + * Description: Instant switching between user accounts in WordPress + * Version: 1.7.0 + * Plugin URI: https://wordpress.org/plugins/user-switching/ + * Author: John Blackbourn & contributors + * Author URI: https://github.com/johnbillion/user-switching/graphs/contributors + * Text Domain: user-switching + * Domain Path: /languages/ + * Network: true + * Requires at least: 5.6 + * Requires PHP: 7.4 + * License URI: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by From 17aa4b79e5039371b8748f6240c1f8e9cac863f0 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 16 Nov 2023 21:19:11 +0000 Subject: [PATCH 264/270] I don't really use this any more. --- composer.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/composer.json b/composer.json index 86d6c64..9f13627 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,6 @@ "codeception/module-db": "^1.0", "codeception/module-webdriver": "^1.0", "codeception/util-universalframework": "^1.0", - "ergebnis/composer-normalize": "^2", "johnbillion/plugin-infrastructure": "dev-trunk", "lucatume/wp-browser": "^3.0.21", "phpcompatibility/phpcompatibility-wp": "2.1.4", @@ -49,7 +48,6 @@ "config": { "allow-plugins": { "composer/installers": true, - "ergebnis/composer-normalize": true, "roots/wordpress-core-installer": true, "dealerdirect/phpcodesniffer-composer-installer": true }, @@ -64,7 +62,6 @@ "scripts": { "test": [ "@composer validate --strict --no-check-lock", - "@composer normalize --dry-run", "@test:phpstan", "@test:phpcs", "@test:start", From 37f60663e5eb4a8d95b73a03a12e13579788b44d Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 16 Nov 2023 21:43:37 +0000 Subject: [PATCH 265/270] Pin some test dependencies because there's nothing worse than random breakages. --- composer.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 9f13627..d1c3094 100644 --- a/composer.json +++ b/composer.json @@ -31,14 +31,14 @@ "codeception/module-webdriver": "^1.0", "codeception/util-universalframework": "^1.0", "johnbillion/plugin-infrastructure": "dev-trunk", - "lucatume/wp-browser": "^3.0.21", + "lucatume/wp-browser": "3.2.1", "phpcompatibility/phpcompatibility-wp": "2.1.4", - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan": "1.10.41", + "phpstan/phpstan-phpunit": "1.3.15", "roots/wordpress-core-installer": "^1.0.0", "roots/wordpress-full": "*", - "szepeviktor/phpstan-wordpress": "1.3.0", - "wp-coding-standards/wpcs": "^3.0.0" + "szepeviktor/phpstan-wordpress": "1.3.2", + "wp-coding-standards/wpcs": "3.0.1" }, "autoload-dev": { "psr-4": { From 314a17a69319fbbdb8adea8f731b800bb5cc068d Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 16 Nov 2023 21:48:31 +0000 Subject: [PATCH 266/270] Rename the integration test files. --- .../{authenticationTest.php => AuthenticationTest.php} | 0 tests/integration/{capabilitiesTest.php => CapabilitiesTest.php} | 0 tests/integration/{pluginTest.php => PluginTest.php} | 0 tests/integration/{sessionsTest.php => SessionsTest.php} | 0 tests/integration/{switchingTest.php => SwitchingTest.php} | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename tests/integration/{authenticationTest.php => AuthenticationTest.php} (100%) rename tests/integration/{capabilitiesTest.php => CapabilitiesTest.php} (100%) rename tests/integration/{pluginTest.php => PluginTest.php} (100%) rename tests/integration/{sessionsTest.php => SessionsTest.php} (100%) rename tests/integration/{switchingTest.php => SwitchingTest.php} (100%) diff --git a/tests/integration/authenticationTest.php b/tests/integration/AuthenticationTest.php similarity index 100% rename from tests/integration/authenticationTest.php rename to tests/integration/AuthenticationTest.php diff --git a/tests/integration/capabilitiesTest.php b/tests/integration/CapabilitiesTest.php similarity index 100% rename from tests/integration/capabilitiesTest.php rename to tests/integration/CapabilitiesTest.php diff --git a/tests/integration/pluginTest.php b/tests/integration/PluginTest.php similarity index 100% rename from tests/integration/pluginTest.php rename to tests/integration/PluginTest.php diff --git a/tests/integration/sessionsTest.php b/tests/integration/SessionsTest.php similarity index 100% rename from tests/integration/sessionsTest.php rename to tests/integration/SessionsTest.php diff --git a/tests/integration/switchingTest.php b/tests/integration/SwitchingTest.php similarity index 100% rename from tests/integration/switchingTest.php rename to tests/integration/SwitchingTest.php From 04fd07a038921211c8a567d412f93d6195c9d1fb Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 16 Nov 2023 21:50:04 +0000 Subject: [PATCH 267/270] Version 1.7.1. --- package-lock.json | 2 +- package.json | 2 +- readme.md | 4 ++-- user-switching.php | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7141915..b74d934 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "user-switching", - "version": "1.7.0", + "version": "1.7.1", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/package.json b/package.json index cc52cce..20a65d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "user-switching", - "version": "1.7.0", + "version": "1.7.1", "description": "Instant switching between user accounts in WordPress.", "license": "GPL-2.0-or-later", "author": "John Blackbourn", diff --git a/readme.md b/readme.md index eb68704..a4cfb78 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ # User Switching -Stable tag: 1.7.0 +Stable tag: 1.7.1 Tested up to: 6.3 License: GPL v2 or later Tags: users, user switching, fast user switching, multisite, woocommerce, buddypress, bbpress @@ -282,7 +282,7 @@ When a user switches to another account, switches off, or switches back, the `us /** * Filters the redirect location after a user switches to another account or switches off. * - * @since 1.7.0 + * @since 1.7.1 * * @param string $redirect_to The target redirect location, or an empty string if none is specified. * @param string|null $redirect_type The redirect type, see the `user_switching::REDIRECT_*` constants. diff --git a/user-switching.php b/user-switching.php index 3a1403e..a128b81 100644 --- a/user-switching.php +++ b/user-switching.php @@ -10,7 +10,7 @@ * * Plugin Name: User Switching * Description: Instant switching between user accounts in WordPress - * Version: 1.7.0 + * Version: 1.7.1 * Plugin URI: https://wordpress.org/plugins/user-switching/ * Author: John Blackbourn & contributors * Author URI: https://github.com/johnbillion/user-switching/graphs/contributors @@ -377,7 +377,7 @@ protected static function get_redirect( WP_User $new_user = null, WP_User $old_u /** * Filters the redirect location after a user switches to another account or switches off. * - * @since 1.7.0 + * @since 1.7.1 * * @param string $redirect_to The target redirect location, or an empty string if none is specified. * @param string|null $redirect_type The redirect type, see the `user_switching::REDIRECT_*` constants. From 9d7c55046669bcb1dc32ed370a0402234da60584 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 16 Nov 2023 21:56:36 +0000 Subject: [PATCH 268/270] Correct these `@since` tags. --- readme.md | 2 +- user-switching.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index a4cfb78..d9f1eb5 100644 --- a/readme.md +++ b/readme.md @@ -282,7 +282,7 @@ When a user switches to another account, switches off, or switches back, the `us /** * Filters the redirect location after a user switches to another account or switches off. * - * @since 1.7.1 + * @since 1.7.0 * * @param string $redirect_to The target redirect location, or an empty string if none is specified. * @param string|null $redirect_type The redirect type, see the `user_switching::REDIRECT_*` constants. diff --git a/user-switching.php b/user-switching.php index a128b81..4aea718 100644 --- a/user-switching.php +++ b/user-switching.php @@ -377,7 +377,7 @@ protected static function get_redirect( WP_User $new_user = null, WP_User $old_u /** * Filters the redirect location after a user switches to another account or switches off. * - * @since 1.7.1 + * @since 1.7.0 * * @param string $redirect_to The target redirect location, or an empty string if none is specified. * @param string|null $redirect_type The redirect type, see the `user_switching::REDIRECT_*` constants. From eedd4511456bd1f7d45eded083606a7ef6840d52 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 16 Nov 2023 22:00:05 +0000 Subject: [PATCH 269/270] Actually bump the tested up to version. --- .github/workflows/acceptance-tests.yml | 2 +- .github/workflows/integration-tests.yml | 3 +-- readme.md | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml index 1c61465..89082fd 100644 --- a/.github/workflows/acceptance-tests.yml +++ b/.github/workflows/acceptance-tests.yml @@ -31,8 +31,8 @@ jobs: matrix: wp: - 'nightly' + - '6.4' - '6.3' - - '6.2' php: - '8.2' - '8.1' diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index c66fa51..917324b 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -32,9 +32,8 @@ jobs: matrix: wp: - 'nightly' + - '6.4' - '6.3' - - '6.2' - - '6.1' php: - '8.2' - '8.1' diff --git a/readme.md b/readme.md index d9f1eb5..7239103 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,7 @@ # User Switching Stable tag: 1.7.1 -Tested up to: 6.3 +Tested up to: 6.4 License: GPL v2 or later Tags: users, user switching, fast user switching, multisite, woocommerce, buddypress, bbpress Contributors: johnbillion From a489687d1237fba0b74e9dea5b5b20f9709bae06 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 16 Nov 2023 22:00:13 +0000 Subject: [PATCH 270/270] Can't exclude this from the deployment. --- .gitattributes | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index e73fc07..a5e4222 100644 --- a/.gitattributes +++ b/.gitattributes @@ -23,5 +23,4 @@ /package.json export-ignore /phpcs.xml.dist export-ignore /phpstan.neon.dist export-ignore -/readme.md export-ignore /SECURITY.md export-ignore