diff --git a/.circleci/config.yml b/.circleci/config.yml index 5bba79b618f3..9cc227255fe3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,14 +9,14 @@ jobs: steps: - checkout - restore_cache: - key: pipenv-v1-{{ checksum "setup.py" }} + key: pipenv-v2-{{ checksum "setup.py" }} # Only install if .venv wasn’t cached. - run: | if [[ ! -e ".venv" ]]; then pipenv install -e .[testing,docs] fi - save_cache: - key: pipenv-v1-{{ checksum "setup.py" }} + key: pipenv-v2-{{ checksum "setup.py" }} paths: - .venv - run: pipenv run ruff check . @@ -29,7 +29,7 @@ jobs: name: Run tests command: | export PYTHONUNBUFFERED=1 - pipenv run python -u runtests.py --parallel=2 + WAGTAIL_CHECK_TEMPLATE_NUMBER_FORMAT=1 pipenv run python -u runtests.py --parallel=2 frontend: docker: @@ -72,27 +72,30 @@ jobs: - attach_workspace: at: ~/project - restore_cache: - key: pipenv-v1-{{ checksum "setup.py" }} + key: pipenv-v2-{{ checksum "setup.py" }} # Only install if .venv wasn’t cached. - run: | if [[ ! -e ".venv" ]]; then pipenv install -e .[testing] fi - save_cache: - key: pipenv-v1-{{ checksum "setup.py" }} + key: pipenv-v2-{{ checksum "setup.py" }} paths: - .venv - restore_cache: - key: ui_tests-npm_integration-v1-{{ checksum "client/tests/integration/package-lock.json" }} + key: ui_tests-npm_integration-v2-{{ checksum "client/tests/integration/package-lock.json" }} # Only install if node_modules wasn’t cached. - run: | if [[ ! -e "client/tests/integration/node_modules" ]]; then npm --prefix ./client/tests/integration ci fi - save_cache: - key: ui_tests-npm_integration-v1-{{ checksum "client/tests/integration/package-lock.json" }} + key: ui_tests-npm_integration-v2-{{ checksum "client/tests/integration/package-lock.json" }} paths: - client/tests/integration/node_modules + # Also cache the global location where Puppeteer stores browsers. + # https://pptr.dev/guides/configuration/#changing-the-default-cache-directory + - ~/.cache/puppeteer - run: pipenv run ./wagtail/test/manage.py migrate - run: command: pipenv run ./wagtail/test/manage.py runserver 0:8000 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ee5eb6dcd0f8..5708dccf9467 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,22 +13,24 @@ concurrency: cancel-in-progress: true # Our test suite should cover: -# - all supported databases against current Python and Django +# - all supported databases against current Python and Django (including psycopg v2 and v3) # - at least one test run for each older supported version of Python and Django # - at least one test run for each supported Elasticsearch version # - a test run against Django's git main and active stable branch (allowing failures) -# - test runs with USE_EMAIL_USER_MODEL=yes and DISABLE_TIMEZONE=yes +# - test runs with USE_EMAIL_USER_MODEL=yes, DISABLE_TIMEZONE=yes and WAGTAIL_CHECK_TEMPLATE_NUMBER_FORMAT=1 # Current configuration: -# - django 4.2, python 3.9, postgres:12, parallel +# - django 4.2, python 3.9, postgres:12, psycopg 2, parallel # - django 4.2, python 3.10, mysql:8.0 -# - django 5.0, python 3.11, sqlite -# - django 5.1, python 3.12, mysql:8.1, parallel +# - django 4.2, python 3.11, mariadb:10.5 +# - django 5.0, python 3.11, sqlite, WAGTAIL_CHECK_TEMPLATE_NUMBER_FORMAT=1 +# - django 5.1, python 3.12, mysql:8.4, parallel, USE_EMAIL_USER_MODEL=yes +# - django 5.1, python 3.12, mariadb:11.4, USE_EMAIL_USER_MODEL=yes # - django 5.1, python 3.12, sqlite, parallel, USE_EMAIL_USER_MODEL=yes -# - django 5.1, python 3.12, postgres:15, parallel, DISABLE_TIMEZONE=yes -# - django stable/5.1.x, python 3.11, postgres:15 (allow failures) -# - django main, python 3.12, postgres:latest, parallel (allow failures) -# - elasticsearch 7, django 4.2, python 3.9, postgres:latest +# - django 5.1, python 3.12, postgres:15, psycopg 3, parallel, DISABLE_TIMEZONE=yes +# - django stable/5.1.x, python 3.11, postgres:15, psycopg 3 (allow failures) +# - django main, python 3.12, postgres:latest, psycopg 3, parallel (allow failures) +# - elasticsearch 7, django 4.2, python 3.9, postgres:latest, psycopg 2 # - opensearch 2, django 5.0, python 3.10, sqlite # - elasticsearch 8, django 5.1, python 3.12, sqlite, USE_EMAIL_USER_MODEL=yes @@ -49,15 +51,16 @@ jobs: include: - python: '3.11' django: 'Django>=5.0,<5.1' + check_template_number_format: '1' - python: '3.12' django: 'Django>=5.1,<5.2' emailuser: emailuser parallel: '--parallel' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} cache: 'pip' @@ -73,11 +76,13 @@ jobs: env: DATABASE_ENGINE: django.db.backends.sqlite3 USE_EMAIL_USER_MODEL: ${{ matrix.emailuser }} + WAGTAIL_CHECK_TEMPLATE_NUMBER_FORMAT: ${{ matrix.check_template_number_format }} - name: Upload coverage data - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: coverage-data + name: coverage-data-${{ github.job }}-${{ strategy.job-index }} path: .coverage.* + include-hidden-files: true test-postgres: runs-on: ubuntu-latest @@ -87,20 +92,24 @@ jobs: include: - python: '3.9' django: 'Django>=4.2,<4.3' + psycopg: 'psycopg2>=2.6' experimental: false parallel: '--parallel' - python: '3.12' django: 'Django>=5.0,<5.1' + psycopg: 'psycopg>=3.1.8' postgres: 'postgres:15' notz: notz experimental: false parallel: '--parallel' - python: '3.11' django: 'git+https://github.com/django/django.git@stable/5.1.x#egg=Django' + psycopg: 'psycopg>=3.1.8' postgres: 'postgres:15' experimental: true - python: '3.12' django: 'git+https://github.com/django/django.git@main#egg=Django' + psycopg: 'psycopg>=3.1.8' experimental: true postgres: 'postgres:latest' parallel: '--parallel' @@ -114,16 +123,16 @@ jobs: options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} cache: 'pip' - name: Install dependencies run: | python -m pip install --upgrade pip - pip install "psycopg2>=2.6" + pip install "${{ matrix.psycopg }}" pip install -e '.[testing]' --config-settings editable_mode=strict pip install "${{ matrix.django }}" ${{ matrix.install_extras }} @@ -139,10 +148,11 @@ jobs: USE_EMAIL_USER_MODEL: ${{ matrix.emailuser }} DISABLE_TIMEZONE: ${{ matrix.notz }} - name: Upload coverage data - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: coverage-data + name: coverage-data-${{ github.job }}-${{ strategy.job-index }} path: .coverage.* + include-hidden-files: true test-mysql: runs-on: ubuntu-latest @@ -153,25 +163,38 @@ jobs: - python: '3.10' django: 'Django>=4.2,<4.3' experimental: false + - python: '3.11' + django: 'Django>=4.2,<4.3' + experimental: false + mysql: 'mariadb:10.5' + - python: '3.12' + django: 'Django>=5.1,<5.2' + experimental: false + mysql: 'mariadb:11.4' + emailuser: emailuser - python: '3.12' django: 'Django>=5.1,<5.2' experimental: false parallel: '--parallel' - mysql: 'mysql:8.1' + mysql: 'mysql:8.4' + emailuser: emailuser services: mysql: image: ${{ matrix.mysql || 'mysql:8.0' }} env: + MARIADB_ROOT_PASSWORD: root + MYSQL_ROOT_PASSWORD: root MYSQL_ALLOW_EMPTY_PASSWORD: yes MYSQL_DATABASE: wagtail + HEALTH_CMD: ${{ startsWith(matrix.mysql, 'mariadb') && 'healthcheck.sh --connect --innodb_initialized' || 'mysqladmin --protocol=tcp ping' }} ports: - 3306:3306 - options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 --cap-add=sys_nice + options: --health-cmd=$HEALTH_CMD --health-interval=10s --health-timeout=5s --health-retries=3 --cap-add=sys_nice steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} cache: 'pip' @@ -189,11 +212,15 @@ jobs: DATABASE_ENGINE: django.db.backends.mysql DATABASE_HOST: '127.0.0.1' DATABASE_USER: root + DATABASE_PASSWORD: root + USE_EMAIL_USER_MODEL: ${{ matrix.emailuser }} + DISABLE_TIMEZONE: ${{ matrix.notz }} - name: Upload coverage data - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: coverage-data + name: coverage-data-${{ github.job }}-${{ strategy.job-index }} path: .coverage.* + include-hidden-files: true test-sqlite-elasticsearch8: runs-on: ubuntu-latest @@ -210,7 +237,7 @@ jobs: sudo sysctl -w vm.swappiness=1 sudo sysctl -w fs.file-max=262144 sudo sysctl -w vm.max_map_count=262144 - - uses: getong/elasticsearch-action@v1.2 + - uses: getong/elasticsearch-action@v1.3 with: elasticsearch version: 8.8.0 host port: 9200 @@ -218,9 +245,9 @@ jobs: host node port: 9300 node port: 9300 discovery type: 'single-node' - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} cache: 'pip' @@ -238,10 +265,11 @@ jobs: DATABASE_ENGINE: django.db.backends.sqlite3 USE_EMAIL_USER_MODEL: ${{ matrix.emailuser }} - name: Upload coverage data - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: coverage-data + name: coverage-data-${{ github.job }}-${{ strategy.job-index }} path: .coverage.* + include-hidden-files: true test-postgres-elasticsearch7: runs-on: ubuntu-latest @@ -272,9 +300,9 @@ jobs: - uses: elastic/elastic-github-actions/elasticsearch@master with: stack-version: 7.6.1 - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} cache: 'pip' @@ -296,10 +324,11 @@ jobs: DATABASE_PASSWORD: postgres USE_EMAIL_USER_MODEL: ${{ matrix.emailuser }} - name: Upload coverage data - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: coverage-data + name: coverage-data-${{ github.job }}-${{ strategy.job-index }} path: .coverage.* + include-hidden-files: true test-sqlite-opensearch2: runs-on: ubuntu-latest @@ -321,9 +350,9 @@ jobs: - uses: ankane/setup-opensearch@v1 with: opensearch-version: 2 - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} cache: 'pip' @@ -341,10 +370,11 @@ jobs: DATABASE_ENGINE: django.db.backends.sqlite3 USE_EMAIL_USER_MODEL: ${{ matrix.emailuser }} - name: Upload coverage data - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: coverage-data + name: coverage-data-${{ github.job }}-${{ strategy.job-index }} path: .coverage.* + include-hidden-files: true coverage: needs: @@ -357,10 +387,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.10' @@ -370,9 +400,10 @@ jobs: pip install coverage - name: Download coverage data - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: - name: coverage-data + pattern: coverage-data-* + merge-multiple: true - name: Combine coverage data run: | @@ -384,12 +415,14 @@ jobs: coverage html --skip-covered --skip-empty - name: Upload HTML report as artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: coverage-report path: coverage_html_report + include-hidden-files: true - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 with: flags: backend + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.gitignore b/.gitignore index 121204e0737e..fb915162ae48 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ npm-debug.log* /.cache/ /.pytest_cache/ /storybook-static +/wagtail/tests/test-media/ ### JetBrains .idea/ diff --git a/.semgrep.yml b/.semgrep.yml index 3cba39ba5329..1fb28d213d60 100644 --- a/.semgrep.yml +++ b/.semgrep.yml @@ -39,6 +39,9 @@ rules: - metavariable-regex: metavariable: $STRING_ID regex: ".*%\\w.*" + paths: + exclude: + - 'wagtail/test/numberformat.py' message: > Do not use anonymous placeholders for translations. Use printf style formatting with named placeholders instead. diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 99b8d4e3b91c..2176d07045c6 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -5,24 +5,52 @@ Changelog ~~~~~~~~~~~~~~~~ * Add formal support for Django 5.1 (Matt Westcott) + * Formalize support for MariaDB (Sage Abdullah, Daniel Black) * Redirect to the last viewed listing page after deleting form submissions (Matthias Brück) * Provide `getTextLabel` method on date / time StreamField blocks (Vaughn Dickson) * Purge frontend cache when modifying redirects (Jake Howard) + * Migrate workflow history views to universal listings (Sage Abdullah) + * Refactor documents views to use universal designs (Sage Abdullah) + * Refactor images views to use universal designs (Sage Abdullah) + * Implement universal listings for workflow usage and page type usage views (Sage Abdullah) * Fix: Prevent page type business rules from blocking reordering of pages (Andy Babic, Sage Abdullah) * Fix: Improve layout of object permissions table (Sage Abdullah) + * Fix: Fix typo in aria-label attribute of page explorer navigation link (Sébastien Corbin) + * Fix: Reinstate transparency indicator on image chooser widgets (Sébastien Corbin) + * Fix: Remove table headers that have no text (Matt Westcott) + * Fix: Fix broken link to user search (Shlomo Markowitz) * Docs: Upgrade Sphinx to 7.3 (Matt Westcott) - * Docs: Document how to customise date/time format settings (Vince Salvino) + * Docs: Document how to customize date/time format settings (Vince Salvino) + * Docs: Create a new documentation section for deployment and move fly.io deployment from the tutorial to this section (Vince Salvino) + * Docs: Clarify process for UserViewSet customisation (Sage Abdullah) * Maintenance: Removed support for Python 3.8 (Matt Westcott) * Maintenance: Drop pytz dependency in favour of `zoneinfo.available_timezones` (Sage Abdullah) * Maintenance: Relax django-taggit dependency to allow 6.0 (Matt Westcott) + * Maintenance: Improve page listing performance (Sage Abdullah) + * Maintenance: Phase out usage of SECRET_KEY in version and icon hashes (Jake Howard) + * Maintenance: Audit all use of localized and non-localized numbers in templates (Matt Westcott) + * Maintenance: Refactor StreamField `get_prep_value` for closer alignment with JSONField (Sage Abdullah) + * Maintenance: Move search implementation logic from generic `IndexView` to `BaseListingView` (Sage Abdullah) + * Maintenance: Upgrade Puppeteer integration tests for reliability (Matt Westcott) + * Maintenance: Restore ability to use `.in_bulk()` on specific querysets under Django 5.2a0 (Sage Abdullah) + * Maintenance: Add generated `test-media` to .gitignore (Shlomo Markowitz) -6.2.1 (xx.xx.20xx) - IN DEVELOPMENT +6.2.2 (xx.xx.xxxx) - IN DEVELOPMENT +~~~~~~~~~~~~~~~~~~ + + * Fix: Fix various instances of `USE_THOUSAND_SEPARATOR` formatting numbers where formatting is invalid (Sébastien Corbin, Matt Westcott) + * Fix: Fix broken link to user search (Shlomo Markowitz) + * Docs: Clarify process for UserViewSet customisation (Sage Abdullah) + + +6.2.1 (20.08.2024) ~~~~~~~~~~~~~~~~~~ * Fix: Handle `child_block` being passed as a kwarg in ListBlock migrations (Matt Westcott) * Fix: Fix broken task type filter in workflow task chooser modal (Sage Abdullah) * Fix: Prevent circular imports between `wagtail.admin.models` and custom user models (Matt Westcott) + * Fix: Ensure that concurrent editing check works for users who only have edit access via workflows (Matt Westcott) 6.2 (01.08.2024) @@ -94,7 +122,7 @@ Changelog * Maintenance: Split `contrib.frontend_cache.backends` into dedicated sub-modules (Andy Babic) * Maintenance: Remove unused `docs/autobuild.sh` script (Sævar Öfjörð Magnússon) * Maintenance: Replace `urlparse` with `urlsplit` to improve performance (Jake Howard) - * Maintenance: Optimise embed finder lookups (Jake Howard) + * Maintenance: Optimize embed finder lookups (Jake Howard) * Maintenance: Improve performance of initial admin loading by moving sprite hashing out of module import time (Jake Howard) * Maintenance: Remove workaround and inline scripts for activating workflow actions (Sage Abdullah) * Maintenance: Prevent `'BlockWidget' object has no attribute '_block_json'` from masking errors during StreamField serialization (Matt Westcott) @@ -159,7 +187,7 @@ Changelog * Update the minimum version of `djangorestframework` to 3.15.1 (Sage Abdullah) * Add support for related fields in generic `IndexView.list_display` (Abdelrahman Hamada) * Improve page fetching logic and cache route results per request (Gordon Pendleton) - * Optimise rewriting of links / embeds in rich text using bulk database lookups (Andy Chosak) + * Optimize rewriting of links / embeds in rich text using bulk database lookups (Andy Chosak) * Add normalization mechanism to StreamField so that assignments and defaults can be passed in a wider range of data types (Joshua Munn, Matt Westcott) * Allow specifying a `STORAGES` alias name for `WAGTAILIMAGES_RENDITION_STORAGE` (Alec Baron) * Update `PASSWORD_REQUIRED_TEMPLATE` setting to `WAGTAIL_PASSWORD_REQUIRED_TEMPLATE` with deprecation of previous naming (Saksham Misra, LB (Ben) Johnston) @@ -568,7 +596,7 @@ Changelog * Support extending Wagtail client-side with Stimulus (LB (Ben) Johnston) * Update all `FieldPanel('title')` examples to use the recommended `TitleFieldPanel('title')` panel (Chinedu Ihedioha) * The `purge_revisions` management command now respects revisions that have a `on_delete=PROTECT` foreign key relation and won't delete them (Neeraj P Yetheendran, Meghana Reddy, Sage Abdullah, Storm Heg) - * Add support for Shift + Click behaviour in form submissions and simple translations submissions (LB (Ben) Johnston) + * Add support for Shift + Click behavior in form submissions and simple translations submissions (LB (Ben) Johnston) * Improve filtering of audit logging based on the user's permissions (Stefan Hammer) * Fix: Ensure that StreamField's `FieldBlock`s correctly set the `required` and `aria-describedby` attributes (Storm Heg) * Fix: Avoid an error when the moderation panel (admin dashboard) contains both snippets and private pages (Matt Westcott) @@ -630,7 +658,7 @@ Changelog * Maintenance: Deprecate legacy URL redirects in `ModelViewSet` and `SnippetViewSet` (Sage Abdullah) * Maintenance: Simplify code for registering page listing action buttons (Matt Westcott) * Maintenance: Removed the unused, legacy, Wagtail userbar views set up for an old iframe approach (Sage Abdullah) - * Maintenance: Optimise `lru_cache` usage (Jake Howard) + * Maintenance: Optimize `lru_cache` usage (Jake Howard) * Maintenance: Implement `date_since` in `get_most_popular` inside `search_promotions.models.Query` (TopDevPros) * Maintenance: Refactor generic view subclasses to better reuse the generic templates and breadcrumbs (Sage Abdullah) * Maintenance: Adopt consistent `classname` (not `classnames`) attributes for all `MenuItem` usage, including deprecation warnings (LB (Ben) Johnston) @@ -770,7 +798,7 @@ Changelog * Maintenance: Optimise use of `specific` on Task and TaskState (Matt Westcott) * Maintenance: Use table UI component for workflow task index view (Matt Westcott) * Maintenance: Make header search available on generic index view (Matt Westcott) - * Maintenance: Update pagination behaviour to reject out-of-range / invalid page numbers (Matt Westcott) + * Maintenance: Update pagination behavior to reject out-of-range / invalid page numbers (Matt Westcott) * Maintenance: Remove color tokens which are duplicates / unused (Thibaud Colas) * Maintenance: Add tests to help with maintenance of theme color tokens (Thibaud Colas) * Maintenance: Split out a base listing view from generic index view (Matt Westcott) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 22da84b787bd..76452d4aa2a3 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -830,6 +830,7 @@ * Vaughn Dickson * Ansuman Shukla * Nayanshi Singh +* Daniel Black ## Translators @@ -850,7 +851,7 @@ * Czech: Ales Dvorak, Jan Feřtek, Martin Galda, IT Management, Tomáš Jeřábek, Vláďa Macek, Eva Mikesova, Mořeplavec, Sophy O, Martina Oleksakova, Kryštof Pilnáček, Tomáš Podivínský, Ivan Pomykacz, Jiri Stepanek, Marek Turnovec, Mirek Zvolský * Danish: Benjamin Bach, Mads Kronborg, MRostgaard, Asger Sørensen * Divehi: Fauzaan Gasim -* Dutch: benny_AT_it_digin.com, Bram, Ramon de Jezus Brecht Dervaux, Harmen, Storm Heg, Kees Hink, Huib Keemink, Franklin Kingma, Maarten Kling, Thijs Kramer, Samuel Leeuwenburg, mahulst, Meteor0id, Rob Moorman, Benjamin van Renterghem, Michael van Tellingen, Arne Turpyn, Coen van der Kamp +* Dutch: benny_AT_it_digin.com, Bram, Ramon de Jezus Brecht Dervaux, Harmen, Storm Heg, Kees Hink, Huib Keemink, Franklin Kingma, Maarten Kling, Thijs Kramer, Samuel Leeuwenburg, mahulst, Meteor0id, Rob Moorman, Benjamin van Renterghem, Michael van Tellingen, Arne Turpyn, Coen van der Kamp, Richard Voorhorst * English (India): Neeraj PY, Apoorv Saini * Estonian: Erlend Eelmets, Martin, Ragnar Rebase * Finnish: Jiri Grönroos, Eetu Häivälä, Niklas Jerva, Aarni Koskela, Rauli Laine, Valter Maasalo, Glen Somerville, Juha Yrjölä diff --git a/README.md b/README.md index 036ffd9e9f97..b98fc7fa01c0 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ Wagtail supports: - Django 4.2.x, 5.0.x and 5.1.x - Python 3.9, 3.10, 3.11 and 3.12 -- PostgreSQL, MySQL and SQLite (with JSON1) as database backends +- PostgreSQL, MySQL, MariaDB and SQLite (with JSON1) as database backends [Previous versions of Wagtail](https://docs.wagtail.org/en/stable/releases/upgrading.html#compatible-django-python-versions) additionally supported Python 2.7, 3.8 and earlier Django versions. diff --git a/client/src/controllers/README.md b/client/src/controllers/README.md index 767af56b595e..f0953b5354f5 100644 --- a/client/src/controllers/README.md +++ b/client/src/controllers/README.md @@ -2,7 +2,7 @@ **Important:** This is a migration in progress, any large refactors or new code should adopt this approach. -- Wagtail uses [Stimulus](https://stimulus.hotwired.dev/) as a way to attach interactive behaviour to DOM elements. +- Wagtail uses [Stimulus](https://stimulus.hotwired.dev/) as a way to attach interactive behavior to DOM elements. - This is a lightweight JavaScript framework that allows a JavaScript class to be attached to any DOM element that adheres to a specific usage of `data-` attributes on the element. - Each file within this folder should contain one Stimulus controller class, using a matching file name (for example `class MyAwesomeController, `MyAwesomeController.ts`, all TitleCase). - Controllers that are included in the `index.ts` default export will automatically be included in the core bundle and provided by default. diff --git a/client/tests/integration/editor.test.js b/client/tests/integration/editor.test.js index 920733deed9a..4f1739d8c859 100644 --- a/client/tests/integration/editor.test.js +++ b/client/tests/integration/editor.test.js @@ -1,3 +1,5 @@ +jest.setTimeout(30000); + describe('Editor', () => { const globalEditorExcludes = '.skiplink, .sidebar__collapse-toggle, #wagtail-sidebar, li[aria-controls^="tab-"]'; diff --git a/client/tests/integration/groups.test.js b/client/tests/integration/groups.test.js index 94593ee91236..1e4a18375422 100644 --- a/client/tests/integration/groups.test.js +++ b/client/tests/integration/groups.test.js @@ -1,7 +1,9 @@ +jest.setTimeout(30000); + describe('Groups', () => { beforeAll(async () => { await page.goto(`${TEST_ORIGIN}/admin/groups/2/`); - }, 10000); + }); it('has the right heading', async () => { expect(await page.title()).toContain('Editing: Editors - Wagtail'); diff --git a/client/tests/integration/homepage.test.js b/client/tests/integration/homepage.test.js index f00b5d608918..71e4e6c2b31e 100644 --- a/client/tests/integration/homepage.test.js +++ b/client/tests/integration/homepage.test.js @@ -1,3 +1,5 @@ +jest.setTimeout(30000); + describe('Homepage', () => { beforeAll(async () => { await page.goto(`${TEST_ORIGIN}/admin/`, { diff --git a/client/tests/integration/listing.test.js b/client/tests/integration/listing.test.js index d4b20e16449f..d2562afc0bc9 100644 --- a/client/tests/integration/listing.test.js +++ b/client/tests/integration/listing.test.js @@ -1,3 +1,5 @@ +jest.setTimeout(30000); + describe('Listing', () => { beforeAll(async () => { await page.goto(`${TEST_ORIGIN}/admin/pages/2/`); diff --git a/client/tests/integration/package-lock.json b/client/tests/integration/package-lock.json index 1b8b3ad91dd4..e3a74dd8ff61 100644 --- a/client/tests/integration/package-lock.json +++ b/client/tests/integration/package-lock.json @@ -10,7 +10,7 @@ "expect-puppeteer": "^6.1.0", "jest": "^27.5.1", "jest-junit": "^13.0.0", - "puppeteer": "^13.4.1" + "puppeteer": "^22.11.2" } }, "node_modules/@ampproject/remapping": { @@ -26,18 +26,18 @@ } }, "node_modules/@axe-core/puppeteer": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@axe-core/puppeteer/-/puppeteer-4.3.1.tgz", - "integrity": "sha512-ojZzd2koeMFj4Crz842g54gU9MEosZA2Vzq8zoRBsT7lQ+EwjASNUfNKQHDhJaO53oEMC7xZv9Y2bhDrAhJRlg==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@axe-core/puppeteer/-/puppeteer-4.9.1.tgz", + "integrity": "sha512-eakSzSS0Zmk7EfX2kUn1jfZsO7gmvjhNnwvBxv9o6HXvwZE5ME/CTi3v2HJMvC+dn3LlznEEdzBB87AyHvcP5A==", "dev": true, "dependencies": { - "axe-core": "^4.3.3" + "axe-core": "~4.9.1" }, "engines": { "node": ">=6.4.0" }, "peerDependencies": { - "puppeteer": ">=1.10.0 <= 10" + "puppeteer": ">=1.10.0" } }, "node_modules/@babel/code-frame": { @@ -974,6 +974,81 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@puppeteer/browsers": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.3.0.tgz", + "integrity": "sha512-ioXoq9gPxkss4MYhD+SFaU9p1IHFUX0ILAWFPyjGaBdjLsYAlZw6j1iLA0N/m12uVHLFDfSYNF7EQccjinIMDA==", + "dev": true, + "dependencies": { + "debug": "^4.3.5", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.4.0", + "semver": "^7.6.3", + "tar-fs": "^3.0.6", + "unbzip2-stream": "^1.4.3", + "yargs": "^17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@puppeteer/browsers/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@puppeteer/browsers/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@puppeteer/browsers/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@puppeteer/browsers/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -1001,6 +1076,12 @@ "node": ">= 6" } }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "dev": true + }, "node_modules/@types/babel__core": { "version": "7.1.18", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.18.tgz", @@ -1109,9 +1190,9 @@ "dev": true }, "node_modules/@types/yauzl": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", - "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "dev": true, "optional": true, "dependencies": { @@ -1262,6 +1343,18 @@ "sprintf-js": "~1.0.2" } }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dev": true, + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1269,14 +1362,20 @@ "dev": true }, "node_modules/axe-core": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.3.5.tgz", - "integrity": "sha512-WKTW1+xAzhMS5dJsxWkliixlO/PqC4VhmO9T4juNYcaTg9jzWiJsou6m5pxWYGfigWbwzJWeFY6z47a+4neRXA==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.9.1.tgz", + "integrity": "sha512-QbUdXJVTpvUTHU7871ppZkdOLBeGUKBQWHkHrvN2V9IQWGMt61zf3B45BtzjxEJzYuj0JBjBZP/hmYS/R9pmAw==", "dev": true, "engines": { "node": ">=4" } }, + "node_modules/b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", + "dev": true + }, "node_modules/babel-jest": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", @@ -1375,6 +1474,52 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/bare-events": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", + "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "dev": true, + "optional": true + }, + "node_modules/bare-fs": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.1.tgz", + "integrity": "sha512-W/Hfxc/6VehXlsgFtbB5B4xFcsCl+pAh30cYhoFyXErf6oGrwjh8SwiPAdHgpmWonKuYpZgGywN0SXt7dgsADA==", + "dev": true, + "optional": true, + "dependencies": { + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "bare-stream": "^2.0.0" + } + }, + "node_modules/bare-os": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.0.tgz", + "integrity": "sha512-v8DTT08AS/G0F9xrhyLtepoo9EJBJ85FRSMbu1pQUlAf6A8T0tEEQGMVObWeqpjhSPXsE0VGlluFBJu2fdoTNg==", + "dev": true, + "optional": true + }, + "node_modules/bare-path": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", + "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "dev": true, + "optional": true, + "dependencies": { + "bare-os": "^2.1.0" + } + }, + "node_modules/bare-stream": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.1.3.tgz", + "integrity": "sha512-tiDAH9H/kP+tvNO5sczyn9ZAA7utrSMobyDchsnyyXBuUe2FSQWbxhtuHB8jwpHYYevVo2UJpcmvvjrbHboUUQ==", + "dev": true, + "optional": true, + "dependencies": { + "streamx": "^2.18.0" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -1395,15 +1540,13 @@ } ] }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "engines": { + "node": ">=10.0.0" } }, "node_modules/brace-expansion": { @@ -1493,7 +1636,7 @@ "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true, "engines": { "node": "*" @@ -1524,14 +1667,24 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001312", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", - "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==", + "version": "1.0.30001646", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001646.tgz", + "integrity": "sha512-dRg00gudiBDDTmUhClSdv3hqRfpbOnU28IpI1T6PBTLWa+kOj0681C8uML3PifYfREuBrVjDGhL3adYpBT6spw==", "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] }, "node_modules/chalk": { "version": "4.1.2", @@ -1558,11 +1711,19 @@ "node": ">=10" } }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true + "node_modules/chromium-bidi": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.6.3.tgz", + "integrity": "sha512-qXlsCmpCZJAnoTYI83Iu6EdYQpMYdVkCfq08KDh2pmlVqK5t5IA9mGs4/LwCwp4fqisSOMXZxP3HIh8w8aRn0A==", + "dev": true, + "dependencies": { + "mitt": "3.0.1", + "urlpattern-polyfill": "10.0.0", + "zod": "3.23.8" + }, + "peerDependencies": { + "devtools-protocol": "*" + } }, "node_modules/ci-info": { "version": "3.3.0", @@ -1654,13 +1815,48 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "node_modules/cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cosmiconfig/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/cosmiconfig/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "dependencies": { - "node-fetch": "2.6.7" + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, "node_modules/cross-spawn": { @@ -1701,6 +1897,15 @@ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "dev": true }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, "node_modules/data-urls": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", @@ -1751,9 +1956,9 @@ } }, "node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -1779,12 +1984,6 @@ "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", "dev": true }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, "node_modules/deepmerge": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", @@ -1794,6 +1993,20 @@ "node": ">=0.10.0" } }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dev": true, + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1813,9 +2026,9 @@ } }, "node_modules/devtools-protocol": { - "version": "0.0.960912", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.960912.tgz", - "integrity": "sha512-I3hWmV9rWHbdnUdmMKHF2NuYutIM2kXz2mdXW8ha7TbRlGTVs+PF+PsB5QWvpCek4Fy9B+msiispCfwlhG5Sqg==", + "version": "0.0.1312386", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1312386.tgz", + "integrity": "sha512-DPnhUXvmvKT2dFA/j7B+riVLUt9Q6RKJlcppojL5CoRywJJKLDYnRlw0gTFKfgDPHP5E04UoB71SxoJlVZy8FA==", "dev": true }, "node_modules/diff-sequences": { @@ -1881,6 +2094,15 @@ "once": "^1.4.0" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -1909,15 +2131,14 @@ } }, "node_modules/escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "dev": true, "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" + "esutils": "^2.0.2" }, "bin": { "escodegen": "bin/escodegen.js", @@ -2046,18 +2267,18 @@ "@types/yauzl": "^2.9.1" } }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, "node_modules/fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -2070,7 +2291,7 @@ "node_modules/fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, "dependencies": { "pend": "~1.2.0" @@ -2115,11 +2336,28 @@ "node": ">= 6" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-extra/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } }, "node_modules/fs.realpath": { "version": "1.0.0", @@ -2189,6 +2427,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-uri": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "dev": true, + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4", + "fs-extra": "^11.2.0" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -2278,9 +2531,9 @@ } }, "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dev": true, "dependencies": { "agent-base": "6", @@ -2331,6 +2584,31 @@ } ] }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -2375,6 +2653,25 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ip-address/node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -3178,6 +3475,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true + }, "node_modules/jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -3310,6 +3613,27 @@ "node": ">=6" } }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonfile/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -3328,19 +3652,6 @@ "node": ">=6" } }, - "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -3462,6 +3773,12 @@ "node": "*" } }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true + }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -3474,12 +3791,6 @@ "node": ">=10" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -3492,24 +3803,13 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", "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": ">= 0.4.0" } }, "node_modules/node-int64": { @@ -3575,23 +3875,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -3628,6 +3911,88 @@ "node": ">=6" } }, + "node_modules/pac-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", + "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", + "dev": true, + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.5", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "dev": true, + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -3688,7 +4053,7 @@ "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "dev": true }, "node_modules/picocolors": { @@ -3730,15 +4095,6 @@ "node": ">=8" } }, - "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/pretty-format": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", @@ -3787,6 +4143,72 @@ "node": ">= 6" } }, + "node_modules/proxy-agent": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", + "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.3", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -3819,27 +4241,38 @@ } }, "node_modules/puppeteer": { - "version": "13.4.1", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-13.4.1.tgz", - "integrity": "sha512-2arcYPEGvLV9HvOw01Zv1b1IAXrMWHqsFJn0Hn00qe9HtCmaF0b8FlrbdLjCIbkaFc6icH5+GqcG8R5KxlJSRg==", + "version": "22.15.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.15.0.tgz", + "integrity": "sha512-XjCY1SiSEi1T7iSYuxS82ft85kwDJUS7wj1Z0eGVXKdtr5g4xnVcbjwxhq5xBnpK/E7x1VZZoJDxpjAOasHT4Q==", "dev": true, "hasInstallScript": true, "dependencies": { - "cross-fetch": "3.1.5", - "debug": "4.3.3", - "devtools-protocol": "0.0.960912", - "extract-zip": "2.0.1", - "https-proxy-agent": "5.0.0", - "pkg-dir": "4.2.0", - "progress": "2.0.3", - "proxy-from-env": "1.1.0", - "rimraf": "3.0.2", - "tar-fs": "2.1.1", - "unbzip2-stream": "1.4.3", - "ws": "8.5.0" + "@puppeteer/browsers": "2.3.0", + "cosmiconfig": "^9.0.0", + "devtools-protocol": "0.0.1312386", + "puppeteer-core": "22.15.0" + }, + "bin": { + "puppeteer": "lib/esm/puppeteer/node/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/puppeteer-core": { + "version": "22.15.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.15.0.tgz", + "integrity": "sha512-cHArnywCiAAVXa3t4GGL2vttNxh7GqXtIYGym99egkNJ3oG//wL9LkvO4WE8W1TJe95t1F1ocu9X4xWaGsOKOA==", + "dev": true, + "dependencies": { + "@puppeteer/browsers": "2.3.0", + "chromium-bidi": "0.6.3", + "debug": "^4.3.6", + "devtools-protocol": "0.0.1312386", + "ws": "^8.18.0" }, "engines": { - "node": ">=10.18.1" + "node": ">=18" } }, "node_modules/querystringify": { @@ -3848,26 +4281,18 @@ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", "dev": true }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/regenerator-runtime": { "version": "0.13.9", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", @@ -3951,26 +4376,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "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/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -4040,6 +4445,56 @@ "node": ">=8" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "dev": true, + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", + "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.1", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -4077,13 +4532,18 @@ "node": ">=10" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "node_modules/streamx": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", + "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", "dev": true, "dependencies": { - "safe-buffer": "~5.2.0" + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" } }, "node_modules/string-length": { @@ -4199,31 +4659,28 @@ "dev": true }, "node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", + "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", "dev": true, "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", - "tar-stream": "^2.1.4" + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0" } }, "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", "dev": true, "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" } }, "node_modules/terminal-link": { @@ -4256,6 +4713,15 @@ "node": ">=8" } }, + "node_modules/text-decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.1.tgz", + "integrity": "sha512-8zll7REEv4GDD3x4/0pW+ppIxSNs7H1J10IKFZsuOMscumCdM2a+toDGLPA3T+1+fLBql4zbt5z83GEQGGV5VA==", + "dev": true, + "dependencies": { + "b4a": "^1.6.4" + } + }, "node_modules/throat": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", @@ -4265,7 +4731,7 @@ "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, "node_modules/tmpl": { @@ -4310,24 +4776,12 @@ "node": ">=6" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", "dev": true }, - "node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -4387,10 +4841,10 @@ "requires-port": "^1.0.0" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "node_modules/urlpattern-polyfill": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", "dev": true }, "node_modules/uuid": { @@ -4455,12 +4909,6 @@ "makeerror": "1.0.12" } }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true - }, "node_modules/whatwg-encoding": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", @@ -4476,16 +4924,6 @@ "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", "dev": true }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "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", @@ -4501,15 +4939,6 @@ "node": ">= 8" } }, - "node_modules/word-wrap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", - "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -4546,16 +4975,16 @@ } }, "node_modules/ws": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", - "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -4629,12 +5058,21 @@ "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } + }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } }, "dependencies": { @@ -4648,12 +5086,12 @@ } }, "@axe-core/puppeteer": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@axe-core/puppeteer/-/puppeteer-4.3.1.tgz", - "integrity": "sha512-ojZzd2koeMFj4Crz842g54gU9MEosZA2Vzq8zoRBsT7lQ+EwjASNUfNKQHDhJaO53oEMC7xZv9Y2bhDrAhJRlg==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@axe-core/puppeteer/-/puppeteer-4.9.1.tgz", + "integrity": "sha512-eakSzSS0Zmk7EfX2kUn1jfZsO7gmvjhNnwvBxv9o6HXvwZE5ME/CTi3v2HJMvC+dn3LlznEEdzBB87AyHvcP5A==", "dev": true, "requires": { - "axe-core": "^4.3.3" + "axe-core": "~4.9.1" } }, "@babel/code-frame": { @@ -5372,8 +5810,64 @@ "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "@puppeteer/browsers": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.3.0.tgz", + "integrity": "sha512-ioXoq9gPxkss4MYhD+SFaU9p1IHFUX0ILAWFPyjGaBdjLsYAlZw6j1iLA0N/m12uVHLFDfSYNF7EQccjinIMDA==", + "dev": true, + "requires": { + "debug": "^4.3.5", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.4.0", + "semver": "^7.6.3", + "tar-fs": "^3.0.6", + "unbzip2-stream": "^1.4.3", + "yargs": "^17.7.2" + }, + "dependencies": { + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + } } }, "@sinonjs/commons": { @@ -5400,6 +5894,12 @@ "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true }, + "@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "dev": true + }, "@types/babel__core": { "version": "7.1.18", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.18.tgz", @@ -5508,9 +6008,9 @@ "dev": true }, "@types/yauzl": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", - "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "dev": true, "optional": true, "requires": { @@ -5615,6 +6115,15 @@ "sprintf-js": "~1.0.2" } }, + "ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dev": true, + "requires": { + "tslib": "^2.0.1" + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -5622,9 +6131,15 @@ "dev": true }, "axe-core": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.3.5.tgz", - "integrity": "sha512-WKTW1+xAzhMS5dJsxWkliixlO/PqC4VhmO9T4juNYcaTg9jzWiJsou6m5pxWYGfigWbwzJWeFY6z47a+4neRXA==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.9.1.tgz", + "integrity": "sha512-QbUdXJVTpvUTHU7871ppZkdOLBeGUKBQWHkHrvN2V9IQWGMt61zf3B45BtzjxEJzYuj0JBjBZP/hmYS/R9pmAw==", + "dev": true + }, + "b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", "dev": true }, "babel-jest": { @@ -5704,22 +6219,63 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "bare-events": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", + "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "dev": true, + "optional": true + }, + "bare-fs": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.1.tgz", + "integrity": "sha512-W/Hfxc/6VehXlsgFtbB5B4xFcsCl+pAh30cYhoFyXErf6oGrwjh8SwiPAdHgpmWonKuYpZgGywN0SXt7dgsADA==", + "dev": true, + "optional": true, + "requires": { + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "bare-stream": "^2.0.0" + } + }, + "bare-os": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.0.tgz", + "integrity": "sha512-v8DTT08AS/G0F9xrhyLtepoo9EJBJ85FRSMbu1pQUlAf6A8T0tEEQGMVObWeqpjhSPXsE0VGlluFBJu2fdoTNg==", + "dev": true, + "optional": true + }, + "bare-path": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", + "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "dev": true, + "optional": true, + "requires": { + "bare-os": "^2.1.0" + } + }, + "bare-stream": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.1.3.tgz", + "integrity": "sha512-tiDAH9H/kP+tvNO5sczyn9ZAA7utrSMobyDchsnyyXBuUe2FSQWbxhtuHB8jwpHYYevVo2UJpcmvvjrbHboUUQ==", + "dev": true, + "optional": true, + "requires": { + "streamx": "^2.18.0" + } + }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true }, - "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } + "basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "dev": true }, "brace-expansion": { "version": "1.1.11", @@ -5781,7 +6337,7 @@ "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true }, "buffer-from": { @@ -5803,9 +6359,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001312", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", - "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==", + "version": "1.0.30001646", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001646.tgz", + "integrity": "sha512-dRg00gudiBDDTmUhClSdv3hqRfpbOnU28IpI1T6PBTLWa+kOj0681C8uML3PifYfREuBrVjDGhL3adYpBT6spw==", "dev": true }, "chalk": { @@ -5824,11 +6380,16 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true + "chromium-bidi": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.6.3.tgz", + "integrity": "sha512-qXlsCmpCZJAnoTYI83Iu6EdYQpMYdVkCfq08KDh2pmlVqK5t5IA9mGs4/LwCwp4fqisSOMXZxP3HIh8w8aRn0A==", + "dev": true, + "requires": { + "mitt": "3.0.1", + "urlpattern-polyfill": "10.0.0", + "zod": "3.23.8" + } }, "ci-info": { "version": "3.3.0", @@ -5912,13 +6473,33 @@ } } }, - "cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, "requires": { - "node-fetch": "2.6.7" + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + } } }, "cross-spawn": { @@ -5955,6 +6536,12 @@ } } }, + "data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "dev": true + }, "data-urls": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", @@ -5995,9 +6582,9 @@ } }, "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", "dev": true, "requires": { "ms": "2.1.2" @@ -6015,18 +6602,23 @@ "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", "dev": true }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, "deepmerge": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", "dev": true }, + "degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dev": true, + "requires": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + } + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -6040,9 +6632,9 @@ "dev": true }, "devtools-protocol": { - "version": "0.0.960912", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.960912.tgz", - "integrity": "sha512-I3hWmV9rWHbdnUdmMKHF2NuYutIM2kXz2mdXW8ha7TbRlGTVs+PF+PsB5QWvpCek4Fy9B+msiispCfwlhG5Sqg==", + "version": "0.0.1312386", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1312386.tgz", + "integrity": "sha512-DPnhUXvmvKT2dFA/j7B+riVLUt9Q6RKJlcppojL5CoRywJJKLDYnRlw0gTFKfgDPHP5E04UoB71SxoJlVZy8FA==", "dev": true }, "diff-sequences": { @@ -6095,6 +6687,12 @@ "once": "^1.4.0" } }, + "env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -6117,15 +6715,14 @@ "dev": true }, "escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "dev": true, "requires": { "esprima": "^4.0.1", "estraverse": "^5.2.0", "esutils": "^2.0.2", - "optionator": "^0.8.1", "source-map": "~0.6.1" } }, @@ -6208,18 +6805,18 @@ "yauzl": "^2.10.0" } }, + "fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, "fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -6232,7 +6829,7 @@ "fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, "requires": { "pend": "~1.2.0" @@ -6268,11 +6865,24 @@ "mime-types": "^2.1.12" } }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true + "fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true + } + } }, "fs.realpath": { "version": "1.0.0", @@ -6320,6 +6930,18 @@ "pump": "^3.0.0" } }, + "get-uri": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "dev": true, + "requires": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4", + "fs-extra": "^11.2.0" + } + }, "glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -6388,9 +7010,9 @@ } }, "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dev": true, "requires": { "agent-base": "6", @@ -6418,6 +7040,24 @@ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, "import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -6450,6 +7090,24 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "requires": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "dependencies": { + "sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + } + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -7076,6 +7734,12 @@ "esprima": "^4.0.0" } }, + "jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true + }, "jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -7164,6 +7828,24 @@ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true + } + } + }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -7176,16 +7858,6 @@ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, "lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -7280,18 +7952,18 @@ "brace-expansion": "^1.1.7" } }, + "mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true + }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, - "mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -7304,14 +7976,11 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } + "netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "dev": true }, "node-int64": { "version": "0.4.0", @@ -7364,20 +8033,6 @@ "mimic-fn": "^2.1.0" } }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -7402,6 +8057,72 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "pac-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", + "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", + "dev": true, + "requires": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.5", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.4" + }, + "dependencies": { + "agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "requires": { + "debug": "^4.3.4" + } + }, + "http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "requires": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + } + }, + "https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "requires": { + "agent-base": "^7.0.2", + "debug": "4" + } + } + } + }, + "pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "dev": true, + "requires": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, "parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -7447,7 +8168,7 @@ "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "dev": true }, "picocolors": { @@ -7477,12 +8198,6 @@ "find-up": "^4.0.0" } }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, "pretty-format": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", @@ -7518,6 +8233,59 @@ "sisteransi": "^1.0.5" } }, + "proxy-agent": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", + "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", + "dev": true, + "requires": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.3", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "dependencies": { + "agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "requires": { + "debug": "^4.3.4" + } + }, + "http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "requires": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + } + }, + "https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "requires": { + "agent-base": "^7.0.2", + "debug": "4" + } + }, + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true + } + } + }, "proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -7547,23 +8315,28 @@ "dev": true }, "puppeteer": { - "version": "13.4.1", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-13.4.1.tgz", - "integrity": "sha512-2arcYPEGvLV9HvOw01Zv1b1IAXrMWHqsFJn0Hn00qe9HtCmaF0b8FlrbdLjCIbkaFc6icH5+GqcG8R5KxlJSRg==", + "version": "22.15.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.15.0.tgz", + "integrity": "sha512-XjCY1SiSEi1T7iSYuxS82ft85kwDJUS7wj1Z0eGVXKdtr5g4xnVcbjwxhq5xBnpK/E7x1VZZoJDxpjAOasHT4Q==", + "dev": true, + "requires": { + "@puppeteer/browsers": "2.3.0", + "cosmiconfig": "^9.0.0", + "devtools-protocol": "0.0.1312386", + "puppeteer-core": "22.15.0" + } + }, + "puppeteer-core": { + "version": "22.15.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.15.0.tgz", + "integrity": "sha512-cHArnywCiAAVXa3t4GGL2vttNxh7GqXtIYGym99egkNJ3oG//wL9LkvO4WE8W1TJe95t1F1ocu9X4xWaGsOKOA==", "dev": true, "requires": { - "cross-fetch": "3.1.5", - "debug": "4.3.3", - "devtools-protocol": "0.0.960912", - "extract-zip": "2.0.1", - "https-proxy-agent": "5.0.0", - "pkg-dir": "4.2.0", - "progress": "2.0.3", - "proxy-from-env": "1.1.0", - "rimraf": "3.0.2", - "tar-fs": "2.1.1", - "unbzip2-stream": "1.4.3", - "ws": "8.5.0" + "@puppeteer/browsers": "2.3.0", + "chromium-bidi": "0.6.3", + "debug": "^4.3.6", + "devtools-protocol": "0.0.1312386", + "ws": "^8.18.0" } }, "querystringify": { @@ -7572,23 +8345,18 @@ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", "dev": true }, + "queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, "regenerator-runtime": { "version": "0.13.9", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", @@ -7648,12 +8416,6 @@ "glob": "^7.1.3" } }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -7708,6 +8470,44 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true + }, + "socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "dev": true, + "requires": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + } + }, + "socks-proxy-agent": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", + "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", + "dev": true, + "requires": { + "agent-base": "^7.1.1", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "dependencies": { + "agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "requires": { + "debug": "^4.3.4" + } + } + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -7739,13 +8539,16 @@ "escape-string-regexp": "^2.0.0" } }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "streamx": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", + "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", "dev": true, "requires": { - "safe-buffer": "~5.2.0" + "bare-events": "^2.2.0", + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" } }, "string-length": { @@ -7828,28 +8631,26 @@ "dev": true }, "tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", + "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", "dev": true, "requires": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0", "pump": "^3.0.0", - "tar-stream": "^2.1.4" + "tar-stream": "^3.1.5" } }, "tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", "dev": true, "requires": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" } }, "terminal-link": { @@ -7873,6 +8674,15 @@ "minimatch": "^3.0.4" } }, + "text-decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.1.tgz", + "integrity": "sha512-8zll7REEv4GDD3x4/0pW+ppIxSNs7H1J10IKFZsuOMscumCdM2a+toDGLPA3T+1+fLBql4zbt5z83GEQGGV5VA==", + "dev": true, + "requires": { + "b4a": "^1.6.4" + } + }, "throat": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", @@ -7882,7 +8692,7 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, "tmpl": { @@ -7918,21 +8728,12 @@ "url-parse": "^1.5.3" } }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", "dev": true }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -7980,10 +8781,10 @@ "requires-port": "^1.0.0" } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "urlpattern-polyfill": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", "dev": true }, "uuid": { @@ -8038,12 +8839,6 @@ "makeerror": "1.0.12" } }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true - }, "whatwg-encoding": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", @@ -8059,16 +8854,6 @@ "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", "dev": true }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "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", @@ -8078,12 +8863,6 @@ "isexe": "^2.0.0" } }, - "word-wrap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", - "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", - "dev": true - }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -8114,9 +8893,9 @@ } }, "ws": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", - "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, "requires": {} }, @@ -8174,12 +8953,18 @@ "yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, "requires": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } + }, + "zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "dev": true } } } diff --git a/client/tests/integration/package.json b/client/tests/integration/package.json index 817ce56de4a5..882c1a86e59b 100644 --- a/client/tests/integration/package.json +++ b/client/tests/integration/package.json @@ -6,6 +6,6 @@ "expect-puppeteer": "^6.1.0", "jest": "^27.5.1", "jest-junit": "^13.0.0", - "puppeteer": "^13.4.1" + "puppeteer": "^22.11.2" } } diff --git a/client/tests/integration/users.test.js b/client/tests/integration/users.test.js index 920474b6b05f..46882a662655 100644 --- a/client/tests/integration/users.test.js +++ b/client/tests/integration/users.test.js @@ -1,3 +1,5 @@ +jest.setTimeout(30000); + describe('Users', () => { beforeAll(async () => { await page.goto(`${TEST_ORIGIN}/admin/users/`); diff --git a/docs/advanced_topics/accessibility_considerations.md b/docs/advanced_topics/accessibility_considerations.md index 4c922ad86c26..a3da86d4b0d1 100644 --- a/docs/advanced_topics/accessibility_considerations.md +++ b/docs/advanced_topics/accessibility_considerations.md @@ -84,7 +84,7 @@ Here are common gotchas to be aware of to make the site’s templates as accessi ### Alt text in templates -See the [content modelling](content_modeling) section above. Additionally, make sure to [customise images’ alt text](image_tag_alt), either setting it to the relevant field, or to an empty string for decorative images, or images where the alt text would be a repeat of other content. +See the [content modelling](content_modeling) section above. Additionally, make sure to [customize images’ alt text](image_tag_alt), either setting it to the relevant field, or to an empty string for decorative images, or images where the alt text would be a repeat of other content. Even when your images have alt text coming directly from the image model, you still need to decide whether there should be alt text for the particular context the image is used in. For example, avoid alt text in listings where the alt text just repeats the listing items’ title. ### Empty heading tags @@ -238,7 +238,7 @@ Some users, such as those with vestibular disorders, may prefer a more static ve ```css @media (prefers-reduced-motion) { - /* styles to apply if a user's device settings are set to reduced motion */ + /* styles to apply if a user's device settings are set to reduced motion */ /* for example, disable animations */ * { animation: none !important; @@ -249,7 +249,6 @@ Some users, such as those with vestibular disorders, may prefer a more static ve Note that `prefers-reduced-motion` is only applied for users who enabled this setting in their operating system or browser. This feature is supported by Chrome, Safari and Firefox. For more information on reduced motion, see the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion). - ## Accessibility resources We focus on considerations specific to Wagtail websites, but there is much more to accessibility. Here are valuable resources to learn more, for developers but also designers and authors: diff --git a/docs/advanced_topics/customisation/custom_page_listings.md b/docs/advanced_topics/customisation/custom_page_listings.md index b3d7362ec2bd..1e8668ba669e 100644 --- a/docs/advanced_topics/customisation/custom_page_listings.md +++ b/docs/advanced_topics/customisation/custom_page_listings.md @@ -1,4 +1,5 @@ (custom_page_listings)= + # Custom page listings Normally, editors navigate through the Wagtail admin interface by following the structure of the page tree. However, this can make it slow to locate a specific page for editing, especially on large sites where pages are organised into a deep hierarchy. @@ -28,7 +29,7 @@ def register_blog_page_listing_viewset(): return blog_page_listing_viewset ``` -The columns of the listing can be customised by overriding the `columns` attribute on the viewset. This should be a list of `wagtail.admin.ui.tables.Column` instances: +The columns of the listing can be customized by overriding the `columns` attribute on the viewset. This should be a list of `wagtail.admin.ui.tables.Column` instances: ```python from wagtail import hooks @@ -44,7 +45,7 @@ class BlogPageListingViewSet(PageListingViewSet): ] ``` -The filtering options for the listing can be customised by overriding the `filterset_class` attribute on the viewset: +The filtering options for the listing can be customized by overriding the `filterset_class` attribute on the viewset: ```python from wagtail import hooks diff --git a/docs/advanced_topics/customisation/custom_user_models.md b/docs/advanced_topics/customisation/custom_user_models.md index 90f3d6813a9d..2a30346b9319 100644 --- a/docs/advanced_topics/customisation/custom_user_models.md +++ b/docs/advanced_topics/customisation/custom_user_models.md @@ -41,13 +41,21 @@ from myapp.models import MembershipStatus class CustomUserEditForm(UserEditForm): - country = forms.CharField(required=True, label=_("Country")) status = forms.ModelChoiceField(queryset=MembershipStatus.objects, required=True, label=_("Status")) + # Use ModelForm's automatic form fields generation for the model's `country` field, + # but use an explicit custom form field for `status`. + class Meta(UserEditForm.Meta): + fields = UserEditForm.Meta.fields | {"country", "status"} + class CustomUserCreationForm(UserCreationForm): - country = forms.CharField(required=True, label=_("Country")) status = forms.ModelChoiceField(queryset=MembershipStatus.objects, required=True, label=_("Status")) + + # Use ModelForm's automatic form fields generation for the model's `country` field, + # but use an explicit custom form field for `status`. + class Meta(UserCreationForm.Meta): + fields = UserCreationForm.Meta.fields | {"country", "status"} ``` ## Extending the create and edit templates @@ -123,13 +131,18 @@ Replace `wagtail.users` in `settings.INSTALLED_APPS` with the path to `CustomUse ```python INSTALLED_APPS = [ ..., + # Make sure you have two separate entries for the following: "myapp", # an app that contains the custom user model "myproject.apps.CustomUsersAppConfig", # a custom app config for the wagtail.users app - # "wagtail.users", + # "wagtail.users", # this should be removed in favour of the custom app config ..., ] ``` +```{warning} +You can also place the `WagtailUsersAppConfig` subclass inside the same `apps.py` file of your custom user model's app (instead of in a `myproject/apps.py` file), but you need to be careful. Make sure to use two separate config classes instead of turning your existing `AppConfig` subclass into a `WagtailUsersAppConfig` subclass, as that would cause Django to pick up your custom user model as being part of `wagtail.users`. You may also need to set {attr}`~django.apps.AppConfig.default` to `True` in your own app's `AppConfig`, unless you already use a dotted path to the app's `AppConfig` subclass in `INSTALLED_APPS`. +``` + The `UserViewSet` class is a subclass of {class}`~wagtail.admin.viewsets.model.ModelViewSet` and thus it supports most of [the customizations available for `ModelViewSet`](generic_views). For example, you can use a custom directory for the templates by setting {attr}`~wagtail.admin.viewsets.model.ModelViewSet.template_prefix`: ```py diff --git a/docs/advanced_topics/customisation/streamfield_blocks.md b/docs/advanced_topics/customisation/streamfield_blocks.md index dff5f4db4ae4..0aaea57b70e9 100644 --- a/docs/advanced_topics/customisation/streamfield_blocks.md +++ b/docs/advanced_topics/customisation/streamfield_blocks.md @@ -92,7 +92,7 @@ A form template for a StructBlock must include the output of `render_form` for e ## Additional JavaScript on `StructBlock` forms -Often it may be desirable to attach custom JavaScript behaviour to a StructBlock form. For example, given a block such as: +Often it may be desirable to attach custom JavaScript behavior to a StructBlock form. For example, given a block such as: ```python class AddressBlock(StructBlock): diff --git a/docs/advanced_topics/index.md b/docs/advanced_topics/index.md index 6886b7d74b75..c57ca6198204 100644 --- a/docs/advanced_topics/index.md +++ b/docs/advanced_topics/index.md @@ -9,7 +9,6 @@ documents/index icons embeds add_to_django_project -deploying performance i18n privacy diff --git a/docs/advanced_topics/performance.md b/docs/advanced_topics/performance.md index cceade7003ca..4830c362d5bc 100644 --- a/docs/advanced_topics/performance.md +++ b/docs/advanced_topics/performance.md @@ -88,7 +88,7 @@ For details on configuring Wagtail for Elasticsearch, see [](wagtailsearch_backe ## Database -Wagtail is tested on PostgreSQL, SQLite, and MySQL. It may work on some third-party database backends as well, but this is not guaranteed. +Wagtail is tested on PostgreSQL, SQLite, MySQL and MariaDB. It may work on some third-party database backends as well, but this is not guaranteed. We recommend PostgreSQL for production use, however, the choice of database ultimately depends on a combination of factors, including personal preference, team expertise, and specific project requirements. The most important aspect is to ensure that your selected database can meet the performance and scalability requirements of your project. diff --git a/docs/advanced_topics/third_party_tutorials.md b/docs/advanced_topics/third_party_tutorials.md index cef1f95d0977..5892e1d54ea2 100644 --- a/docs/advanced_topics/third_party_tutorials.md +++ b/docs/advanced_topics/third_party_tutorials.md @@ -6,6 +6,7 @@ from third-party developers. Some of the older links may not apply to the latest Wagtail versions. ``` +- [Deploying Wagtail on Divio](https://docs.divio.com/en/latest/introduction/wagtail/) (~June 2024) - [Upgrading Wagtail (from 2.5 to 6.0)](https://learnwagtail.com/blog/category/upgrading-wagtail/) (18 April 2024) - [Using Wagtail Form Templates in Software Development Projects](https://devcodef1.com/news/1211030/wagtail-form-templates-in-sd-projects) (9 April 2024) - [Build an Intuitive Link StructBlock in Wagtail: Simplifying Link Management for Content Editors](https://enzedonline.com/en/tech-blog/build-an-intuitive-link-structblock-in-wagtail-simplifying-link-management-for-content-editors/) (9 March 2024) diff --git a/docs/contributing/security.md b/docs/contributing/security.md index f74319f9f17a..4ed346d90648 100644 --- a/docs/contributing/security.md +++ b/docs/contributing/security.md @@ -53,7 +53,7 @@ On the day of disclosure, we will take the following steps: The commit messages for these patches will indicate that they are for security issues, but will not describe the issue in any detail; instead, they will warn of upcoming disclosure. 2. Issue the relevant release(s), by placing new packages on [the Python Package Index](https://pypi.org/project/wagtail/), tagging the new release(s) in Wagtail's GitHub repository and updating Wagtail's [release notes](../releases/index). 3. Publish a [security advisory](https://github.com/wagtail/wagtail/security/advisories?state=published) on Wagtail's GitHub repository. This describes the issue and its resolution in detail, pointing to the relevant patches and new releases, and crediting the reporter of the issue (if the reporter wishes to be publicly identified) -4. Post a notice to the [Wagtail discussion board](https://github.com/wagtail/wagtail/discussions), [Slack workspace](https://wagtail.org/slack/) and Twitter feed ([\@WagtailCMS](https://twitter.com/wagtailcms)) that links to the security advisory. +4. Post a notice to the [Wagtail discussion board](https://github.com/wagtail/wagtail/discussions), [Slack workspace](https://wagtail.org/slack/) and X feed ([\@WagtailCMS](https://x.com/wagtailcms)) that links to the security advisory. If a reported issue is believed to be particularly time-sensitive -- due to a known exploit in the wild, for example -- the time between advance notification and public disclosure may be shortened considerably. diff --git a/docs/deploy/flyio.md b/docs/deploy/flyio.md new file mode 100644 index 000000000000..7eafa636aab2 --- /dev/null +++ b/docs/deploy/flyio.md @@ -0,0 +1,486 @@ +# Deploying Wagtail with Fly.io + Backblaze + +This tutorial will use two platforms to deploy your site. You'll host your site on [fly.io](https://fly.io) and serve your site's images on [Backblaze](https://www.backblaze.com). + +You can use fly.io to host your site and serve your images. However, storing your images on a platform other than the one hosting your site provides better performance, security, and reliability. + +```{note} +In this tutorial, you'll see "yourname" several times. Replace it with a name of your choice. +``` + +## Setup Backblaze B2 Cloud Storage + +To serve your images, set up a Backblaze B2 storage following these steps: + +1. Visit the Backblaze [website](https://www.backblaze.com) in your browser. +2. Click **Products** from the top navigation and then select **B2 Cloud Storage** from the dropdown. +3. Sign up to Backblaze B2 Cloud Storage by following these steps: + + a. Enter your email address and password. + b. Select the appropriate region. + c. Click **Sign Up Now**. + +4. Verify your email by following these steps: + + a. Go to **Account > My Settings** in your side navigation. + b. Click **Verify Email** in the **Security section**. + c. Enter your sign-up email address and then click send **Send Code**. + d. Check your email inbox or spam folder for the verification email. + e. Click the verification link or use the verification code. + +5. Create a Bucket by going to **B2 Cloud Storage > Bucket** and clicking **Create a Bucket**. +6. Go to **B2 Cloud Storage > Bucket** and then click **Create a Bucket**. +7. Add your Bucket information as follows: + +| Bucket information | Instruction | +| ------------------- | ------------------------------------------------------------------ | +| Bucket Unique Name | Use a unique Bucket name. For example,_yourname-wagtail-portfolio_ | +| Files in Bucket are | Select **Public** | +| Default Encryption | Select **Disable** | +| Object Lock | Select **Disable** | + +8. Click **Create a Bucket**. + +## Link your site to Backblaze B2 Cloud Storage + +After setting up your Backblaze B2 Cloud Storage, you must link it to your portfolio site. + +Start by creating a `.env.production` file at the root of your project directory. At this stage, your project directory should look like this: + +```text +mysite/ +├── base +├── blog +├── home +├── media +├── mysite +├── portfolio +├── search +├── .dockerignore +├── .gitignore +├── .env.production +├── Dockerfile +├── manage.py +├── mysite/ +└── requirements.txt +``` + +Now add the following environment variables to your `.env.production` file: + +```text +AWS_STORAGE_BUCKET_NAME= +AWS_S3_ENDPOINT_URL=https:// +AWS_S3_REGION_NAME= +AWS_S3_ACCESS_KEY_ID= +AWS_S3_SECRET_ACCESS_KEY= +DJANGO_ALLOWED_HOSTS= +DJANGO_CSRF_TRUSTED_ORIGINS=https:// +DJANGO_SETTINGS_MODULE=mysite.settings.production +``` + +### Fill in your Backblaze B2 bucket information + +The next step is to provide values for your environment variables. In your `.env.production` file, use your Backblaze B2 bucket information as values for your environment variables as follows: + +| Environment variable | Instruction | +| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| AWS_STORAGE_BUCKET_NAME | Use your Backblaze B2 bucket name | +| AWS_S3_ENDPOINT_URL | Use the Backblaze B2 endpoint URL. For example, _https://s3.us-east-005.backblazeb2.com_ | +| AWS_S3_REGION_NAME | Determine your bucket's region from the endpoint URL. For example, if your endpoint URL is _s3.us-east-005.backblazeb2.com_, then your bucket's region is _us-east-005_ | +| AWS_S3_ACCESS_KEY_ID | Leave this empty for now | +| AWS_S3_SECRET_ACCESS_KEY | Leave this empty for now | +| DJANGO_ALLOWED_HOSTS | Leave this empty for now | +| DJANGO_CSRF_TRUSTED_ORIGINS | Use _https://_ | +| DJANGO_SETTINGS_MODULE | Use _mysite.settings.production_ | + +In the preceding table, you didn't provide values for your `AWS_S3_ACCESS_KEY_ID`, `AWS_S3_SECRET_ACCESS_KEY`, and `DJANGO_ALLOWED_HOSTS`. + +To get values for your `AWS_S3_ACCESS_KEY_ID` and `AWS_S3_SECRET_ACCESS_KEY`, follow these steps: + +1. Log in to your Backblaze B2 account. +2. Navigate to **Account > Application Keys**. +3. Click **Add a New Application Key**. +4. Configure the application key settings as follows: + +| Setting | Instruction | +| --------------------------- | -------------------------------------------------- | +| Name of Key | Provide a unique name | +| Allow access to Buckets | Choose the Backblaze B2 bucket you created earlier | +| Type of Access | Select **Read and Write** | +| Allow List All Bucket Names | Leave this unticked | +| File name prefix | Leave field empty | +| Duration (seconds) | Leave field empty | + +5. Click **Create New Key**. + +Now, use your `keyID` as the value of `AWS_S3_ACCESS_KEY_ID` and `applicationKey` for `AWS_S3_SECRET_ACCESS_KEY` in your `.env.production` file: + +| Environment variable | Instruction | +| ------------------------ | --------------------------- | +| AWS_S3_ACCESS_KEY_ID | Use your **keyID** | +| AWS_S3_SECRET_ACCESS_KEY | Use your **applicationKey** | + +At this stage, the content of your `.env.production` file looks like this: + +```text +AWS_STORAGE_BUCKET_NAME=yourname-wagtail-portfolio +AWS_S3_ENDPOINT_URL=https://s3.us-east-005.backblazeb2.com +AWS_S3_REGION_NAME=us-east-005 +AWS_S3_ACCESS_KEY_ID=your Backblaze keyID +AWS_S3_SECRET_ACCESS_KEY=your Backblaze applicationKey +DJANGO_ALLOWED_HOSTS= +DJANGO_CSRF_TRUSTED_ORIGINS=https:// +DJANGO_SETTINGS_MODULE=mysite.settings.production +``` + +```{note} +The Backblaze B2 storage uses _AWS_ and _S3_ because it works like Amazon Web Services’ S3. + +Do not commit or share your `.env.production `file. Anyone with the variables can access your site. + +If you lost your secret application key, create a new key following the preceding instructions. +``` + +For more information on how to set up your Backblaze B2 Cloud Storage, read the [Backblaze B2 Cloud Storage Documentation](https://www.backblaze.com/docs/cloud-storage/). + +## Set up Fly.io + +Now that you've linked your site to your Backblaze storage, it's time to set up Fly.io to host your site. + +To set up your Fly.io account, follow these steps: + +1. Visit [Fly.io](https://fly.io/) in your browser. +2. Click **Sign Up**. +3. Sign up using your GitHub account, Google account, or the email option. +4. Check your email inbox for the verification link to verify your email. + +```{note} +If your email verification fails, go to your Fly.io [Dashboard](https://fly.io/dashboard) and try again. +``` + +5. Go to **Dashboard > Billing** and click **Add credit card** to add your credit card. + +```{note} +Adding your credit card allows you to create a project in Fly.io. Fly.io won't charge you after adding your credit card. +``` + +6. [Install flyctl](https://fly.io/docs/hands-on/install-flyctl/) by navigating to your project directory and then running the following command in your terminal: + +On macOS: + +```sh +# If you have the Homebrew package manager installed, run the following command: +brew install flyctl + +# If you don't have the Homebrew package manager installed, run the following command: +curl -L https://fly.io/install.sh | sh +``` + +On Linux: + +```sh +curl -L https://fly.io/install.sh | sh +``` + +On Windows, navigate to your project directory on **PowerShell**, activate your environment and run the following command: + +```doscon +pwsh -Command "iwr https://fly.io/install.ps1 -useb | iex" +``` + +```{note} +If you get an error on Windows saying the term `pwsh` is not recognized, install [PowerShell MSI](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.3#installing-the-msi-package) and then rerun the preceding Windows command. +``` + +7. [Sign in](https://fly.io/docs/hands-on/sign-in/) to your Fly.io by running the following command: + +```sh +fly auth login +``` + +If you use Microsoft WSL, then run: + +```doscon +ln -s /usr/bin/wslview /usr/local/bin/xdg-open +``` + +```{note} +If you successfully install flyctl but get an error saying "`fly` is not recognized" or "flyctl: command not found error", then you must add flyctl to your PATH. For more information, read [Getting flyctl: command not found error post install](https://community.fly.io/t/getting-flyctl-command-not-found-error-post-install/4954/1). +``` + +8. Create your Fly.io project by running `fly launch`. Then press `y` to configure the settings. +9. You will be taken to an admin screen on fly.io. Fill out the fields as follows: + +| Field | Instruction | +| ------------------------------ | ------------------------------------------------------------------------------------ | +| Choose a region for deployment | Select the region closest to the _AWS_S3_REGION_NAME_ in your _env.production_ file. | +| CPU & Memory | VM Size - shared-cpu-1x VM Memory - 512 MB | +| Database | Fly Postgres - choose smallest option | + +click confirm **Confirm settings** + +```{note} +Not creating the database directly with the application leads to the app and the database not connected. +If the app is going to be launched again using fly launch, +it's recommended to create a new database with the launch of the app through the web UI. +``` + +10. Back in your terminal, answer the resulting prompt questions as follows: + +| Question | Instruction | +| ------------------------------ | ----------- | +| Overwrite ".../.dockerignore"? | Enter _y_ | +| Overwrite ".../Dockerfile"? | Enter _y_ | + +The `fly launch` command creates two new files, `Dockerfile` and `fly.toml`, in your project directory. + +If you use a third-party app terminal like the Visual Studio Code terminal, you may get an error creating your Postgres database. To rectify this error, follow these steps: + +1. Delete `fly.toml` file from your project directory. +2. Go to your Fly.io account in your browser and click **Dashboard**. +3. Click the created app in your **Apps** list. +4. Click **Settings** in your side navigation. +5. Click **Delete app**. +6. Enter the name your app. +7. Click **Yes delete it**. +8. Repeat steps 3, 4, 5, 6, and 7 for all apps in your **Apps** list. +9. Run the `fly launch` command in your built-in terminal or PowerShell MSI on Windows. + +## Customize your site to use Fly.io + +Now, you must configure your portfolio site for the final deployment. + +The `fly launch` command creates two new files, `Dockerfile` and `fly.toml`, in your project directory. + +Add the following to your `.gitignore` file to make Git ignore your environment files: + +``` +.env* +``` + +Also, add the following to your `.dockerignore` file to make Docker ignore your environment and media files: + +``` +.env* +media +``` + +Configure your Fly.io to use `1` worker. This allows your site to work better with Fly.io's low memory allowance. To do this, modify the last line of your `Dockerfile` as follows: + +``` +CMD ["gunicorn", "--bind", ":8000", "--workers", "1", "mysite.wsgi"] +``` + +Also, check if your `fly.toml` file has the following: + +```toml +[deploy] + release_command = "python manage.py migrate --noinput" +``` + +Your `fly.toml` file should look as follows: + +```toml +app = "yourname-wagtail-portfolio" +primary_region = "lhr" +console_command = "/code/manage.py shell" + +[build] + +# add the deploy command: +[deploy] + release_command = "python manage.py migrate --noinput" + +[env] + PORT = "8000" + +[http_service] + internal_port = 8000 + force_https = true + auto_stop_machines = true + auto_start_machines = true + min_machines_running = 0 + processes = ["app"] + +[[statics]] + guest_path = "/code/static" + url_prefix = "/static/" +``` + +Now add your production dependencies by replacing the content of your `requirements.txt` file with the following: + +```text +Django>=4.2,<4.3 +wagtail==5.1.1 +gunicorn>=21.2.0,<22.0.0 +psycopg[binary]>=3.1.10,<3.2.0 +dj-database-url>=2.1.0,<3.0.0 +whitenoise>=5.0,<5.1 +django-storages[s3]>=1.14.0,<2.0.0 +``` + +The preceding dependencies ensure that the necessary tools and libraries are in place to run your site successfully on the production server. The following are the explanations for the dependencies you may be unaware of: + +1. `gunicorn` is a web server that runs your site in Docker. +2. `psycopg` is a PostgreSQL adapter that connects your site to a PostgreSQL database. +3. `dj-database-url` is a package that simplifies your database configurations and connects to your site to a PostgreSQL database. +4. `whitenoise` is a Django package that serves static files. +5. `django-storages` is a Django library that handles your file storage and connects to your Backblaze B2 storage. + +Replace the content of your `mysite/settings/production.py` file with the following: + +```python +import os +import random +import string +import dj_database_url + +from .base import * + +DEBUG = False + +DATABASES = { + "default": dj_database_url.config( + conn_max_age=600, + conn_health_checks=True + ) +} + +SECRET_KEY = os.environ["SECRET_KEY"] + +SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") + +SECURE_SSL_REDIRECT = True + +ALLOWED_HOSTS = os.getenv("DJANGO_ALLOWED_HOSTS", "*").split(",") + +CSRF_TRUSTED_ORIGINS = os.getenv("DJANGO_CSRF_TRUSTED_ORIGINS", "").split(",") + +EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" + +MIDDLEWARE.append("whitenoise.middleware.WhiteNoiseMiddleware") +STORAGES["staticfiles"]["BACKEND"] = "whitenoise.storage.CompressedManifestStaticFilesStorage" + +if "AWS_STORAGE_BUCKET_NAME" in os.environ: + AWS_STORAGE_BUCKET_NAME = os.getenv("AWS_STORAGE_BUCKET_NAME") + AWS_S3_REGION_NAME = os.getenv("AWS_S3_REGION_NAME") + AWS_S3_ENDPOINT_URL = os.getenv("AWS_S3_ENDPOINT_URL") + AWS_S3_ACCESS_KEY_ID = os.getenv("AWS_S3_ACCESS_KEY_ID") + AWS_S3_SECRET_ACCESS_KEY = os.getenv("AWS_S3_SECRET_ACCESS_KEY") + + INSTALLED_APPS.append("storages") + + STORAGES["default"]["BACKEND"] = "storages.backends.s3boto3.S3Boto3Storage" + + AWS_S3_OBJECT_PARAMETERS = { + 'CacheControl': 'max-age=86400', + } + +LOGGING = { + "version": 1, + "disable_existing_loggers": False, + "handlers": { + "console": { + "class": "logging.StreamHandler", + }, + }, + "loggers": { + "django": { + "handlers": ["console"], + "level": os.getenv("DJANGO_LOG_LEVEL", "INFO"), + }, + }, +} + +WAGTAIL_REDIRECTS_FILE_STORAGE = "cache" + +try: + from .local import * +except ImportError: + pass +``` + +The explanation of some of the code in your `mysite/settings/production.py` file is as follows: + +1. `DEBUG = False` turns off debugging for the production environment. It's important for security and performance. +2. `SECRET_KEY = os.environ["SECRET_KEY"]` retrieves the project's secret key from your environment variable. +3. `SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")` ensures that Django can detect a secure HTTPS connection if you deploy your site behind a reverse proxy like Heroku. +4. `SECURE_SSL_REDIRECT = True` enforces HTTPS redirect. This ensures that all connections to the site are secure. +5. `ALLOWED_HOSTS = os.getenv("DJANGO_ALLOWED_HOSTS", "*").split(",")` defines the hostnames that can access your site. It retrieves its values from the `DJANGO_ALLOWED_HOSTS` environment variable. If no specific hosts are defined, it defaults to allowing all hosts. +6. `EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"` configures your site to use the console email backend. You can configure this to use a proper email backend for sending emails. +7. `WAGTAIL_REDIRECTS_FILE_STORAGE = "cache"` configures the file storage for Wagtail's redirects. Here, you set it to use cache. + +Now, complete the configuration of your environment variables by modifying your `.env.production` file as follows: + +| Environment variable | Instruction | +| --------------------------- | ----------------------------------------------------------------------------------------------------- | +| DJANGO_ALLOWED_HOSTS | This must match your fly.io project name. For example, _yourname-wagtail-portfolio.fly.dev_ | +| DJANGO_CSRF_TRUSTED_ORIGINS | This must match your project’s domain name. For example, _https://yourname-wagtail-portfolio.fly.dev_ | + +The content of your `.env.production` file should now look like this: + +```text +AWS_STORAGE_BUCKET_NAME=yourname-wagtail-portfolio +AWS_S3_ENDPOINT_URL=https://s3.us-east-005.backblazeb2.com +AWS_S3_REGION_NAME=us-east-005 +AWS_S3_ACCESS_KEY_ID=your Backblaze keyID +AWS_S3_SECRET_ACCESS_KEY=your Backblaze applicationKey +DJANGO_ALLOWED_HOSTS=yourname-wagtail-portfolio.fly.dev +DJANGO_CSRF_TRUSTED_ORIGINS=https://yourname-wagtail-portfolio.fly.dev +DJANGO_SETTINGS_MODULE=mysite.settings.production +``` + +Set the secrets for Fly.io to use by running: + +```sh +flyctl secrets import < .env.production +``` + +On Windows, run the following command in your PowerShell MSI: + +```doscon +Get-Content .env.production | flyctl secrets import +``` + +Finally, deploy your site to Fly.io by running the following command: + +```sh +fly deploy --ha=false +``` + +```{note} +Running "fly deploy" creates two machines for your app. Using the "--ha=false" flag creates one machine for your app. +``` + +Congratulations! Your site is now live. However, you must add content to it. Start by creating an admin user for your live site. Run the following command: + +```sh +flyctl ssh console +``` + +Then run: + +```sh +DJANGO_SUPERUSER_USERNAME=username DJANGO_SUPERUSER_EMAIL=mail@example.com DJANGO_SUPERUSER_PASSWORD=password python manage.py createsuperuser --noinput +``` + +```{note} +Ensure you replace _username_, _mail@example.com_, and _password_ with a username, email address, and password of your choice. +``` + +For more information on how to set up your Django project on Fly.io, read [Django on Fly.io](https://fly.io/docs/django/). + +## Add content to your live site + +All this while, you've been adding content to your site in the local environment. Now that your site is live on a server, you must add content to the live site. To add content to your live site, go to ` https://yourname-wagtail-portfolio.fly.dev/admin/` in your browser and follow the steps in the following sub-sections of the tutorial: + +- [Add content to your homepage](add_content_to_your_homepage) +- [Add your social media links](add_your_social_media_links) +- [Add footer text](add_footer_text) +- [Add pages to your site menu](add_pages_to_your_site_menu) +- [Add your contact information](add_your_contact_information) +- [Add your resume](add_your_resume) + +```{note} +If you encounter errors while trying to access your live site in your browser, check your application logs in your Fly.io Dashboard. To check your application logs, click **Dashboard > Apps > yourname-wagtail-portfolio > Monitoring** +``` diff --git a/docs/deploy/index.md b/docs/deploy/index.md new file mode 100644 index 000000000000..dc33ab447866 --- /dev/null +++ b/docs/deploy/index.md @@ -0,0 +1,64 @@ +(deployment_guide)= + +# Deploying & Hosting Wagtail + +```{toctree} +--- +maxdepth: 2 +hidden: True +--- +flyio +under_the_hood +``` + +Once you've built your Wagtail site, it's time to release it upon the rest of the internet. + +Wagtail is built on Django, and so the vast majority of the deployment steps and considerations for deploying Django are also true for Wagtail. We recommend choosing one of the hosting providers listed below. + +## Choosing a Hosting Provider + +Several hosting providers offer varying levels of support for Wagtail. We’ve organized them into three categories: + +- Wagtail-level support (easiest deployment). +- Python-level support (requires some knowledge of WSGI and file storage). +- Infrastructure-level support (requires knowledge of Linux). + +## Wagtail-Level Support + +These hosting providers offer first-class support for Wagtail deployments and installations, designed to make it as easy as possible to run a Wagtail site. + +### [CodeRed Cloud](https://www.codered.cloud/) + +- Website & pricing: [codered.cloud](https://www.codered.cloud/) +- Wagtail deployment guide: [CodeRed Wagtail Quickstart](https://www.codered.cloud/docs/wagtail/quickstart/) +- From the vendor: + > CodeRed Cloud is inspired by simplicity and “it just works” philosophy. No special packages or 3rd party services required! Free plans are available, and every plan includes a database, media hosting, daily backups, and more. + +### [Divio](https://djtpwt04.eu1.hs-sales-engage.com/Ctc/ZX+23284/djTPWt04/Jks2-6qcW69sMD-6lZ3mWW33N3pF6nlTpxVDmYY_72St44W7WcQZB34Gy_XN564tjxCW9wwW5Qzqq_86S04ZW5kzL9r5ys--sVvWPSq5z_wp5N12NMjlDS290W5xpV801l1QbQW7j0r971B8PwHW1W5N0V4xkzQ6W8FC3C22m3qTjN8DmFHVNg0KDW3cH_jp15CHYGW8h-X0L1qP3r0W8JgZRg7fSp6zW2C1WtR62rTTTW6dpn2Z7GQWB9W5xl4kn8J8lCyW93H_KT1yxPkff1QGBGP04) + +- Website & pricing: [divio.com](https://djtpwt04.eu1.hs-sales-engage.com/Ctc/ZX+23284/djTPWt04/JkM2-6qcW6N1vHY6lZ3pcW2JS-Gx5G-DYfW4MFT8W98G6c6W2DvSTZ7k5hvnF8LfVdx35GmW4T-BzQ2FHjC3N7h3DCyP3BP6W53fnKx7Dp2cwVPnVy56y1fhBW95B9N892LpSlW2BrD5X6hxBcdW6zBY_-42g5FzW4glb7F9hGYY5Vtf9vk8Rkb0CVVCVkz7HrszGN2DfZ1YfDtr4W4rC-NF938nXqW5QxZ__7jcyFDW7Psq7r6CPmPGW3Fgrpq4wKDtkW7BqyqN86tW0tW6jzdpG117J1vW4J69cg1DXj0Vf4bg65P04) +- Wagtail deployment guide: [Divio Wagtail Setup Guide](https://djtpwt04.eu1.hs-sales-engage.com/Ctc/ZX+23284/djTPWt04/JkM2-6qcW6N1vHY6lZ3pcW2JS-Gx5G-DYfW4MFT8W98G6c6W2DvSTZ7k5hvnF8LfVdx35GmW4T-BzQ2FHjC3N7h3DCyP3BP6W53fnKx7Dp2cwVPnVy56y1fhBW95B9N892LpSlW2BrD5X6hxBcdW6zBY_-42g5FzW4glb7F9hGYY5Vtf9vk8Rkb0CVVCVkz7HrszGN2DfZ1YfDtr4W4rC-NF938nXqW5QxZ__7jcyFDW7Psq7r6CPmPGW3Fgrpq4wKDtkW7BqyqN86tW0tW6jzdpG117J1vW4J69cg1DXj0Vf4bg65P04) +- From the vendor: + > Divio is a cloud hosting platform designed to simplify the development and deployment of containerized web applications. It integrates smoothly with Wagtail, providing developers with tools to efficiently manage web applications. Divio proactively manages and supports state-of-the-art cloud services, ensuring that your Wagtail applications are scalable, secure, and reliable. The platform’s user-friendly interface makes it easy to develop, deploy, manage, and maintain your web applications. With features like automated backups and staging environments, Divio handles the technical infrastructure, allowing you to focus on building and maintaining your Wagtail sites with confidence. + +## Python-Level Support + +These hosting providers offer Python environments as a service. Usually, you will need to configure a WSGI server, file storage for media hosting, and a database. + +### Fly.io with Backblaze + +Read our guide on [deploying to Fly.io](flyio). + +## Infrastructure-Level Support + +These hosting providers offer the tools needed to run a Linux server, database, file storage, etc. Popular infrastructure providers include: **AWS, Azure, Digital Ocean, Google Cloud, and Linode**. + +## Others + +Some examples of deployments on a few hosting platforms can be found in [](/advanced_topics/third_party_tutorials). This is not a complete list of platforms where Wagtail can run, nor is it necessarily the only way to run Wagtail there. + +For a technical deep-dive into the many aspects of Wagtail hosting, see [](under_the_hood). + +--- + +_Are you a hosting provider who supports Wagtail, and want to add yourself to this list? See if you meet our [requirements for hosting providers](https://github.com/wagtail/wagtail/wiki/Wagtail-Hosting-Providers)._ diff --git a/docs/advanced_topics/deploying.md b/docs/deploy/under_the_hood.md similarity index 79% rename from docs/advanced_topics/deploying.md rename to docs/deploy/under_the_hood.md index 01ee2afa79bd..d1dd690ec7a7 100644 --- a/docs/advanced_topics/deploying.md +++ b/docs/deploy/under_the_hood.md @@ -1,8 +1,6 @@ -(deployment_guide)= +# Wagtail Deployment: Under the Hood -# Deploying Wagtail - -Once you've built your Wagtail site, it's time to release it upon the rest of the internet. +This doc provides a technical deep-dive into Wagtail hosting concepts. Most likely, you'll want to [choose a hosting provider](index.md) instead. Wagtail is built on Django, and so the vast majority of the deployment steps and considerations for deploying Django are also true for Wagtail. We recommend reading Django's ["How to deploy Django"](inv:django#howto/deployment/index) documentation. @@ -52,15 +50,15 @@ If you would like to serve your images from a separate asset server or CDN, you Document serving is controlled by the [WAGTAILDOCS_SERVE_METHOD](wagtaildocs_serve_method) method. When using `FileSystemStorage`, documents are stored in a `documents` subdirectory within your site's `MEDIA_ROOT`. In this case, `WAGTAILDOCS_SERVE_METHOD` defaults to `serve_view`, where Wagtail serves the document through a Django view that enforces privacy checks. This has the following implications: -* **You should block direct access to the `documents` subdirectory of `MEDIA_ROOT` within your web server configuration.** This prevents users from bypassing [collection privacy settings](https://guide.wagtail.org/en-latest/how-to-guides/manage-collections/#privacy-settings) by accessing documents at their direct URL. -* Documents are served as downloads rather than displayed in the browser (unless specified explicitly via [](wagtaildocs_inline_content_types)) - this ensures that if the document is a type that can contain scripts (such as HTML or SVG), the browser is prevented from executing them. -* However, since the document is served through the Django application server, this may consume more server resources than serving the document directly from the web server. +- **You should block direct access to the `documents` subdirectory of `MEDIA_ROOT` within your web server configuration.** This prevents users from bypassing [collection privacy settings](https://guide.wagtail.org/en-latest/how-to-guides/manage-collections/#privacy-settings) by accessing documents at their direct URL. +- Documents are served as downloads rather than displayed in the browser (unless specified explicitly via [](wagtaildocs_inline_content_types)) - this ensures that if the document is a type that can contain scripts (such as HTML or SVG), the browser is prevented from executing them. +- However, since the document is served through the Django application server, this may consume more server resources than serving the document directly from the web server. The alternative serve methods `'direct'` and `'redirect'` work by serving the documents directly from `MEDIA_ROOT`. This means it is not possible to block direct access to the `documents` subdirectory, and so users may bypass permission checks by accessing the direct URL. Also, in the case that users with access to the Wagtail admin are not fully trusted, you will need to take additional steps to prevent the execution of scripts in documents: -* The `WAGTAILDOCS_EXTENSIONS` setting may be used to restrict uploaded documents to an "allow list" of safe types. -* The web server can be configured to return a `Content-Security-Policy: default-src 'none'` header for files within the `documents` subdirectory, which will prevent the execution of scripts in those files. -* The web server can be configured to return a `Content-Disposition: attachment` header for files within the `documents` subdirectory, which will force the browser to download the file rather than displaying it inline. +- The `WAGTAILDOCS_EXTENSIONS` setting may be used to restrict uploaded documents to an "allow list" of safe types. +- The web server can be configured to return a `Content-Security-Policy: default-src 'none'` header for files within the `documents` subdirectory, which will prevent the execution of scripts in those files. +- The web server can be configured to return a `Content-Disposition: attachment` header for files within the `documents` subdirectory, which will force the browser to download the file rather than displaying it inline. If a remote ("cloud") storage backend is used, the serve method will default to `'redirect'` and the document will be served directly from the cloud storage file url. In this case, users may be able to bypass permission checks, and scripts within documents may be executed (depending on the cloud storage service's configuration). However, the impact of cross-site scripting attacks is reduced, as the document is served from a different domain to the main site. @@ -77,7 +75,7 @@ The django-storages Amazon S3 backends (`storages.backends.s3boto.S3BotoStorage` ### Cache -Wagtail is designed to take adavantage of Django's [cache framework](inv:django#topics/cache) when available to accelerate page loads. The cache is especially useful for the Wagtail admin, which can't take advantage of conventional CDN caching. +Wagtail is designed to take advantage of Django's [cache framework](inv:django#topics/cache) when available to accelerate page loads. The cache is especially useful for the Wagtail admin, which can't take advantage of conventional CDN caching. Wagtail supports any of Django's cache backend, however we recommend against using one tied to the specific process or environment Django is running (eg `FileBasedCache` or `LocMemCache`). @@ -97,7 +95,7 @@ Your production site should be as fast and performant as possible. For tips on h ## Deployment examples -Some examples of deployments on a few hosting platforms can be found in [](./third_party_tutorials). This is not a complete list of platforms where Wagtail can run, nor is it necessarily the only way to run Wagtail there. +Some examples of deployments on a few hosting platforms can be found in [](/advanced_topics/third_party_tutorials). This is not a complete list of platforms where Wagtail can run, nor is it necessarily the only way to run Wagtail there. An example of a production Wagtail site is [guide.wagail.org](https://guide.wagtail.org/), which is [open-source](https://github.com/wagtail/guide) and runs on Heroku. More information on its hosting environment can be found in [its documentation](https://github.com/wagtail/guide/blob/main/docs/hosting-environment.md). diff --git a/docs/extending/admin_views.md b/docs/extending/admin_views.md index f23c865725bb..bcc43de0511e 100644 --- a/docs/extending/admin_views.md +++ b/docs/extending/admin_views.md @@ -246,7 +246,7 @@ class CalendarViewSet(ViewSet): menu_label = "Calendar" icon = "date" # The `name` will be used for both the URL prefix and the URL namespace. - # They can be customised individually via `url_prefix` and `url_namespace`. + # They can be customized individually via `url_prefix` and `url_namespace`. name = "calendar" def get_urlpatterns(self): diff --git a/docs/extending/custom_tasks.md b/docs/extending/custom_tasks.md index 9cffced979e9..c88220d483aa 100644 --- a/docs/extending/custom_tasks.md +++ b/docs/extending/custom_tasks.md @@ -129,7 +129,7 @@ class UserApprovalTask(Task): (custom_tasks_behavior)= -## Customising behaviour +## Customising behavior Both `Task` and `TaskState` have a number of methods that can be overridden to implement custom behavior. Here are some of the most useful: diff --git a/docs/getting_started/integrating_into_django.md b/docs/getting_started/integrating_into_django.md index 9ac93826db38..c9512b53a0bd 100644 --- a/docs/getting_started/integrating_into_django.md +++ b/docs/getting_started/integrating_into_django.md @@ -74,7 +74,7 @@ Add a `WAGTAILDOCS_EXTENSIONS` setting to specify the file types that Wagtail wi WAGTAILDOCS_EXTENSIONS = ['csv', 'docx', 'key', 'odt', 'pdf', 'pptx', 'rtf', 'txt', 'xlsx', 'zip'] ``` -Various other settings are available to configure Wagtail's behaviour - see [Settings](/reference/settings). +Various other settings are available to configure Wagtail's behavior - see [Settings](/reference/settings). ## URL configuration diff --git a/docs/getting_started/tutorial.md b/docs/getting_started/tutorial.md index e9a38bcce15d..6e5eefca6039 100644 --- a/docs/getting_started/tutorial.md +++ b/docs/getting_started/tutorial.md @@ -304,7 +304,7 @@ python manage.py migrate ``` Also, since the model name is `BlogIndexPage`, the default template name, -unless you override it, is `blog_index_page.html`. Django looks for a template whose name matches the name of your Page model within the templates directory in your blog app folder. You can override this default behaviour if you want to. To create a template for the +unless you override it, is `blog_index_page.html`. Django looks for a template whose name matches the name of your Page model within the templates directory in your blog app folder. You can override this default behavior if you want to. To create a template for the `BlogIndexPage` model, create a file at the location `blog/templates/blog/blog_index_page.html`. ```{note} diff --git a/docs/index.rst b/docs/index.rst index bc0c1c1513a4..a0cb7111e99a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -45,6 +45,7 @@ Index advanced_topics/index extending/index reference/index + deploy/index support editor_manual/index contributing/index diff --git a/docs/reference/contrib/forms/customization.md b/docs/reference/contrib/forms/customization.md index 64feb0f1ed3a..d5e217bfc382 100644 --- a/docs/reference/contrib/forms/customization.md +++ b/docs/reference/contrib/forms/customization.md @@ -588,7 +588,7 @@ class FormPage(AbstractEmailForm): (custom_form_submission_listing)= -## Customise form submissions listing in Wagtail Admin +## Customize form submissions listing in Wagtail Admin The Admin listing of form submissions can be customized by setting the attribute `submissions_list_view_class` on your FormPage model. diff --git a/docs/reference/contrib/table_block.md b/docs/reference/contrib/table_block.md index ba037295f54e..10cd97a2045b 100644 --- a/docs/reference/contrib/table_block.md +++ b/docs/reference/contrib/table_block.md @@ -89,12 +89,12 @@ default_table_options = { ### Configuration Options -Every key in the `table_options` dictionary maps to a [handsontable](https://handsontable.com/) option. These settings can be changed to alter the behaviour of tables in Wagtail. The following options are available: +Every key in the `table_options` dictionary maps to a [handsontable](https://handsontable.com/) option. These settings can be changed to alter the behavior of tables in Wagtail. The following options are available: - [minSpareRows](https://handsontable.com/docs/6.2.2/Options.html#minSpareRows) - The number of rows to append to the end of an empty grid. The default setting is 0. - [startRows](https://handsontable.com/docs/6.2.2/Options.html#startRows) - The default number of rows for a new table. - [startCols](https://handsontable.com/docs/6.2.2/Options.html#startCols) - The default number of columns for new tables. -- [colHeaders](https://handsontable.com/docs/6.2.2/Options.html#colHeaders) - Can be set to `True` or `False`. This setting designates if new tables should be created with column headers. **Note:** this only sets the behaviour for newly created tables. Page editors can override this by checking the “Column header” checkbox in the table editor in the Wagtail admin. +- [colHeaders](https://handsontable.com/docs/6.2.2/Options.html#colHeaders) - Can be set to `True` or `False`. This setting designates if new tables should be created with column headers. **Note:** this only sets the behavior for newly created tables. Page editors can override this by checking the “Column header” checkbox in the table editor in the Wagtail admin. - [rowHeaders](https://handsontable.com/docs/6.2.2/Options.html#rowHeaders) - Operates the same as `colHeaders` to designate if new tables should be created with the first column as a row header. Just like `colHeaders` this option can be overridden by the page editor in the Wagtail admin. - [contextMenu](https://handsontable.com/docs/6.2.2/Options.html#contextMenu) - Enables or disables the Handsontable right-click menu. By default this is set to `True`. Alternatively you can provide a list or a dictionary with [specific options](https://handsontable.com/docs/6.2.2/demo-context-menu.html#page-specific). - [editor](https://handsontable.com/docs/6.2.2/Options.html#editor) - Defines the editor used for table cells. The default setting is text. diff --git a/docs/reference/hooks.md b/docs/reference/hooks.md index 819178082e26..4609c3999507 100644 --- a/docs/reference/hooks.md +++ b/docs/reference/hooks.md @@ -410,8 +410,9 @@ Return a QuerySet of `Permission` objects to be shown in the Groups administrati Add buttons to the user list. This hook takes two parameters: -- `user`: The user object to generate the button for -- `request_user`: The currently logged-in user + +- `user`: The user object to generate the button for +- `request_user`: The currently logged-in user This example will add a simple button to the listing if the currently logged-in user is a superuser: diff --git a/docs/reference/management_commands.md b/docs/reference/management_commands.md index 8c8dad8359eb..4cd75f52bf3c 100644 --- a/docs/reference/management_commands.md +++ b/docs/reference/management_commands.md @@ -162,7 +162,7 @@ This does not remove unused rendition images, this can be done by clearing the f Options: -- `--purge-only` : +- `--purge-only` : This argument will purge all image renditions without regenerating them. They will be regenerated when next requested. (convert_mariadb_uuids)= diff --git a/docs/reference/pages/model_reference.md b/docs/reference/pages/model_reference.md index 76f09d9b4e9e..7951215f22e4 100644 --- a/docs/reference/pages/model_reference.md +++ b/docs/reference/pages/model_reference.md @@ -340,7 +340,7 @@ See also [django-treebeard](https://django-treebeard.readthedocs.io/en/latest/in class BreadPage(Page): ... - # default + # default private_page_options = ['password', 'groups', 'login'] # disable shared password diff --git a/docs/reference/settings.md b/docs/reference/settings.md index 871d38de1f3e..8733e0e639da 100644 --- a/docs/reference/settings.md +++ b/docs/reference/settings.md @@ -776,7 +776,7 @@ See [](private_pages) for more details. TAGGIT_CASE_INSENSITIVE = True ``` -Tags are case-sensitive by default ('music' and 'Music' are treated as distinct tags). In many cases the reverse behaviour is preferable. +Tags are case-sensitive by default ('music' and 'Music' are treated as distinct tags). In many cases the reverse behavior is preferable. ### `TAG_SPACES_ALLOWED` diff --git a/docs/releases/5.0.md b/docs/releases/5.0.md index 4e09de85aa24..df90a6f985f1 100644 --- a/docs/releases/5.0.md +++ b/docs/releases/5.0.md @@ -461,7 +461,7 @@ Stimulus [targets](https://stimulus.hotwired.dev/reference/targets) and [actions * `` - any element can be the button label (not just `em`) * ` diff --git a/wagtail/admin/templates/wagtailadmin/generic/history_results.html b/wagtail/admin/templates/wagtailadmin/generic/history_results.html deleted file mode 100644 index fd01dbfa53a0..000000000000 --- a/wagtail/admin/templates/wagtailadmin/generic/history_results.html +++ /dev/null @@ -1 +0,0 @@ -{% extends "wagtailadmin/generic/index_results.html" %} diff --git a/wagtail/admin/templates/wagtailadmin/generic/index.html b/wagtail/admin/templates/wagtailadmin/generic/index.html index 58e86c1451da..18a48d7b4ec4 100644 --- a/wagtail/admin/templates/wagtailadmin/generic/index.html +++ b/wagtail/admin/templates/wagtailadmin/generic/index.html @@ -13,3 +13,20 @@ {% include "wagtailadmin/shared/header.html" with title=page_title subtitle=page_subtitle action_url=header_action_url action_text=header_action_label action_icon=header_action_icon extra_actions=extra_actions icon=header_icon search_url=search_url search_form=search_form search_results_url=index_results_url only %} {% endif %} {% endblock %} + +{% block listing %} + {% comment %} + DEPRECATED: This block override is for supporting views that have filters + but not using breadcrumbs (thus have no slim_header to put the filters in). + There is no longer such a view in Wagtail core, but we keep this block + until we can enforce the use of breadcrumbs in all listing views. + {% endcomment %} + {% if filters and not breadcrumbs_items %} +
+ {{ block.super }} + {% include "wagtailadmin/shared/filters.html" %} +
+ {% else %} + {{ block.super }} + {% endif %} +{% endblock %} diff --git a/wagtail/admin/templates/wagtailadmin/generic/index_results.html b/wagtail/admin/templates/wagtailadmin/generic/index_results.html index 12d2aba8015c..893fc60cfe1c 100644 --- a/wagtail/admin/templates/wagtailadmin/generic/index_results.html +++ b/wagtail/admin/templates/wagtailadmin/generic/index_results.html @@ -1,47 +1,21 @@ {% extends "wagtailadmin/generic/listing_results.html" %} {% load i18n wagtailadmin_tags %} -{% block before_results %} - {{ block.super }} - +{% block other_searches %} {% if is_searching and view.show_other_searches %}
{% search_other %}
{% endif %} - - {% if not object_list %} - {# pass, to allow the same logic as `if object_list and (is_searching or is_filtering)` #} - {% elif is_searching or is_filtering %} -
-

- {% blocktrans trimmed count counter=items_count %} - There is {{ counter }} match - {% plural %} - There are {{ counter }} matches - {% endblocktrans %} -

-
- {% endif %} {% endblock %} {% block no_results_message %} - {% fragment as no_results_message %} - {% if is_searching or is_filtering %} - {% blocktrans trimmed with model_name=model_opts.verbose_name_plural asvar no_results_text %} - No {{ model_name }} match your query. - {% endblocktrans %} - {% elif add_url %} - {% blocktrans trimmed with model_name=model_opts.verbose_name_plural asvar no_results_text %} - There are no {{ model_name }} to display. Why not add one? - {% endblocktrans %} - {% else %} - {% blocktrans trimmed with model_name=model_opts.verbose_name_plural asvar no_results_text %} - There are no {{ model_name }} to display. - {% endblocktrans %} - {% endif %} - {{ no_results_text|capfirst }} - {% endfragment %} - -

{{ no_results_message }}

+ {% if add_url and not is_searching and not is_filtering %} + {% blocktrans trimmed with model_name=verbose_name_plural asvar no_results_text %} + There are no {{ model_name }} to display. Why not add one? + {% endblocktrans %} +

{{ no_results_text|capfirst }}

+ {% else %} + {{ block.super }} + {% endif %} {% endblock %} diff --git a/wagtail/admin/templates/wagtailadmin/generic/inspect.html b/wagtail/admin/templates/wagtailadmin/generic/inspect.html index 41ae158dd16d..8da7689be85e 100644 --- a/wagtail/admin/templates/wagtailadmin/generic/inspect.html +++ b/wagtail/admin/templates/wagtailadmin/generic/inspect.html @@ -1,5 +1,5 @@ {% extends "wagtailadmin/generic/base.html" %} -{% load i18n wagtailadmin_tags %} +{% load i18n wagtailadmin_tags l10n %} {% block main_content %} {% block fields_output %} @@ -11,7 +11,7 @@ {% if field.component %} {% component field.component %} {% else %} - {{ field.value }} + {{ field.value|localize }} {% endif %} {% endfor %} diff --git a/wagtail/admin/templates/wagtailadmin/generic/listing.html b/wagtail/admin/templates/wagtailadmin/generic/listing.html index 450b8dfd8a7c..53d92e19213a 100644 --- a/wagtail/admin/templates/wagtailadmin/generic/listing.html +++ b/wagtail/admin/templates/wagtailadmin/generic/listing.html @@ -1,29 +1,23 @@ {% extends "wagtailadmin/generic/base.html" %} {% load i18n %} -{% block main_header %} - {% if not breadcrumbs_items %} - {% include "wagtailadmin/shared/header.html" with title=page_title subtitle=page_subtitle action_url=header_action_url action_text=header_action_label icon=header_icon only %} - {% endif %} -{% endblock %} - {% block content %} + {% comment %} + Override the content block instead of main_content so we get the full-width layout without the nice-padding. + However, this means we need to include the header block again (and only do {{ block.super }} inside it). + {% endcomment %} + {% block header %} {{ block.super }} {% endblock %} {% block listing %} - + +{% endblock %} + +{% block no_results_message %} + {# This view has a custom no results message using the alert h2 like the results count message #} +{% endblock %} diff --git a/wagtail/admin/templates/wagtailadmin/pages/usage_results.html b/wagtail/admin/templates/wagtailadmin/pages/usage_results.html deleted file mode 100644 index 3dac2d1e11d1..000000000000 --- a/wagtail/admin/templates/wagtailadmin/pages/usage_results.html +++ /dev/null @@ -1,6 +0,0 @@ -{% extends "wagtailadmin/generic/listing_results.html" %} -{% load i18n %} - -{% block no_results_message %} -

{% trans 'No pages use' %} "{{ page_class.get_verbose_name }}".

-{% endblock %} diff --git a/wagtail/admin/templates/wagtailadmin/permissions/includes/collection_member_permissions_formset.html b/wagtail/admin/templates/wagtailadmin/permissions/includes/collection_member_permissions_formset.html index 26364df5960b..9e23fa51817a 100644 --- a/wagtail/admin/templates/wagtailadmin/permissions/includes/collection_member_permissions_formset.html +++ b/wagtail/admin/templates/wagtailadmin/permissions/includes/collection_member_permissions_formset.html @@ -26,7 +26,6 @@ {% for codename, short_label, long_label in formset.permission_types %} {{ short_label }} {% endfor %} - diff --git a/wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_types_usage.html b/wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_types_usage.html index e4843bd229d4..953d0fb15185 100644 --- a/wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_types_usage.html +++ b/wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_types_usage.html @@ -42,9 +42,9 @@ {% if page_type.count > 0 %} - {{ page_type.count }} + {{ page_type.count|intcomma }} {% else %} - {{ page_type.count }} + {{ page_type.count|intcomma }} {% endif %} diff --git a/wagtail/admin/templates/wagtailadmin/shared/editing_sessions/module.html b/wagtail/admin/templates/wagtailadmin/shared/editing_sessions/module.html index c5b5152451d6..62b536b85613 100644 --- a/wagtail/admin/templates/wagtailadmin/shared/editing_sessions/module.html +++ b/wagtail/admin/templates/wagtailadmin/shared/editing_sessions/module.html @@ -36,7 +36,7 @@ {% if revision_id %} {# The ID of the latest revision that was known when this module was initially loaded #} - + {% endif %}
{% component sessions_list %} diff --git a/wagtail/admin/templates/wagtailadmin/shared/forms/single_checkbox.html b/wagtail/admin/templates/wagtailadmin/shared/forms/single_checkbox.html index 88d56b9e3274..4807db5f5404 100644 --- a/wagtail/admin/templates/wagtailadmin/shared/forms/single_checkbox.html +++ b/wagtail/admin/templates/wagtailadmin/shared/forms/single_checkbox.html @@ -1,5 +1,6 @@ {# Render a single checkbox with text center-aligned. #} +{% load l10n %} diff --git a/wagtail/admin/templates/wagtailadmin/shared/pagination_nav.html b/wagtail/admin/templates/wagtailadmin/shared/pagination_nav.html index 5ca2faf86e4a..deafbfaa9be7 100644 --- a/wagtail/admin/templates/wagtailadmin/shared/pagination_nav.html +++ b/wagtail/admin/templates/wagtailadmin/shared/pagination_nav.html @@ -9,7 +9,7 @@ {% resolve_url linkurl as url_path %}