diff --git a/.github/actions/setup-env/action.yml b/.github/actions/setup-env/action.yml new file mode 100644 index 0000000..b20f5c9 --- /dev/null +++ b/.github/actions/setup-env/action.yml @@ -0,0 +1,31 @@ +name: Setup Node and Yarn Dependencies +description: Configures Node.js, prepares Yarn config, restores cache, and installs dependencies. + +inputs: + node-version: + description: Node.js version to use. + required: true + +runs: + using: composite + steps: + - name: Use Node.js ${{ inputs.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ inputs.node-version }} + + - name: Yarn configuration + shell: bash + run: make .yarnrc.yml + + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: .yarn + key: ${{ runner.OS }}-node-${{ inputs.node-version }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.OS }}-node-${{ inputs.node-version }}-yarn- + + - name: Install dependencies + shell: bash + run: yarn install diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5d32bbc..3d6a969 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,47 +1,156 @@ name: Tests -on: [push, pull_request] +on: + push: + branches: + - '**' + pull_request: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: + pr-check: + runs-on: ubuntu-latest + + outputs: + has_open_pr: ${{ steps.detect.outputs.has_open_pr }} + + steps: + - name: Detect open pull request for current branch + id: detect + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + + if [[ "${{ github.event_name }}" != "push" || "${{ github.ref }}" == "refs/heads/main" ]]; then + echo "has_open_pr=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + branch="${GITHUB_REF#refs/heads/}" + head="${GITHUB_REPOSITORY_OWNER}:${branch}" + api_url="https://api.github.com/repos/${GITHUB_REPOSITORY}/pulls" + + count="$( + curl -fsSL \ + -H "Authorization: Bearer ${GH_TOKEN}" \ + -H "Accept: application/vnd.github+json" \ + --get "${api_url}" \ + --data-urlencode "state=open" \ + --data-urlencode "head=${head}" \ + --data-urlencode "per_page=1" \ + | python3 -c 'import json,sys; print(len(json.load(sys.stdin)))' + )" + + if [[ "${count}" -gt 0 ]]; then + echo "has_open_pr=true" >> "$GITHUB_OUTPUT" + else + echo "has_open_pr=false" >> "$GITHUB_OUTPUT" + fi + eslint: + needs: pr-check + if: github.event_name != 'push' || github.ref == 'refs/heads/main' || needs.pr-check.outputs.has_open_pr != 'true' runs-on: ubuntu-latest strategy: matrix: - node-version: [ 22.x ] + node-version: [ 22.x, 24.x ] steps: - name: Using branch ${{ github.ref }} for repository ${{ github.repository }}. uses: actions/checkout@v4 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 + - name: Setup Node and dependencies + uses: ./.github/actions/setup-env with: node-version: ${{ matrix.node-version }} - - name: Yarn configuration - run: make .yarnrc.yml + - name: Run eslint + run: yarn eslint + + tests: + needs: eslint + + timeout-minutes: 90 + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [ 22.x, 24.x ] + + steps: + - name: Using branch ${{ github.ref }} for repository ${{ github.repository }}. + uses: actions/checkout@v4 + + - name: Setup Node and dependencies + uses: ./.github/actions/setup-env + with: + node-version: ${{ matrix.node-version }} - - name: Cache dependencies - id: cache-deps - uses: actions/cache@v4 + - name: Run tests + if: matrix.node-version != '24.x' + run: yarn test + + - name: Install Playwright Chromium + if: matrix.node-version == '24.x' + run: yarn playwright install --with-deps chromium + + - name: Run merged coverage + if: matrix.node-version == '24.x' + run: | + rm -rf coverage .nyc_output + mkdir -p coverage/.parts .nyc_output + yarn test --coverage --coverage.provider=istanbul --coverage.reporter=json --coverage.reportsDirectory=coverage/unit + yarn test:e2e:coverage + cp coverage/unit/coverage-final.json coverage/.parts/unit.json + cp coverage/e2e-react/coverage-final.json coverage/.parts/e2e-react.json + cp coverage/e2e-vue/coverage-final.json coverage/.parts/e2e-vue.json + yarn nyc merge coverage/.parts .nyc_output/coverage-final.json >/dev/null + yarn nyc report + yarn nyc report --reporter=json-summary >/dev/null + yarn node --experimental-strip-types scripts/show-total-coverage.ts + + - name: Upload merged coverage artifacts + if: matrix.node-version == '24.x' && github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: actions/upload-artifact@v4 with: - path: .yarn - key: ${{ runner.OS }}-node-${{ matrix.node-version }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.OS }}-node-${{ matrix.node-version }}-yarn- + name: coverage-node-24 + path: | + coverage/lcov.info + coverage/coverage-summary.json + if-no-files-found: error - - name: Install dependencies - run: yarn install + codecov: + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + needs: tests - - name: Run eslint - run: yarn eslint + runs-on: ubuntu-latest - tests: + steps: + - name: Using branch ${{ github.ref }} for repository ${{ github.repository }}. + uses: actions/checkout@v4 + + - name: Download merged coverage artifacts + uses: actions/download-artifact@v4 + with: + name: coverage-node-24 + path: coverage + + - name: Upload merged coverage to Codecov + uses: codecov/codecov-action@v4 + with: + files: coverage/lcov.info + flags: combined + name: combined-coverage + fail_ci_if_error: true + verbose: true + + storybook-tests: needs: eslint timeout-minutes: 60 @@ -50,31 +159,25 @@ jobs: strategy: matrix: - node-version: [ 22.x ] + node-version: [ 22.x, 24.x ] steps: - name: Using branch ${{ github.ref }} for repository ${{ github.repository }}. uses: actions/checkout@v4 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 + - name: Setup Node and dependencies + uses: ./.github/actions/setup-env with: node-version: ${{ matrix.node-version }} - - name: Yarn configuration - run: make .yarnrc.yml + - name: Build React Storybook + run: yarn workspace @modulify/m3-react storybook:build --test --quiet - - name: Cache dependencies - id: cache-deps - uses: actions/cache@v4 - with: - path: .yarn - key: ${{ runner.OS }}-node-${{ matrix.node-version }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.OS }}-node-${{ matrix.node-version }}-yarn- + - name: Build Vue Storybook + run: yarn workspace @modulify/m3-vue storybook:build --test --quiet - - name: Install dependencies - run: yarn install + - name: Run React Storybook smoke tests + run: yarn workspace @modulify/m3-react test:smoke - - name: Run tests - run: yarn test \ No newline at end of file + - name: Run Vue Storybook smoke tests + run: yarn workspace @modulify/m3-vue test:smoke diff --git a/.gitignore b/.gitignore index 8da80c9..bdc7c42 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ !.yarnrc.yml.dist coverage/ +.nyc_output/ dist/ dist-storybook/ node_modules/ diff --git a/.nycrc.json b/.nycrc.json new file mode 100644 index 0000000..2df0868 --- /dev/null +++ b/.nycrc.json @@ -0,0 +1,13 @@ +{ + "all": false, + "cache": false, + "check-coverage": false, + "temp-dir": ".nyc_output", + "report-dir": "coverage", + "reporter": [ + "text", + "text-summary", + "html", + "lcovonly" + ] +} diff --git a/AGENTS.md b/AGENTS.md index df23d79..33ec614 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -143,3 +143,5 @@ Global examples: eslint rule updates, shared dependency updates, repository-leve `skills/yarn-lock-conflict-resolution/SKILL.md`. - For coverage deficit analysis and recovery strategy, use the local skill: `skills/coverage-recovery/SKILL.md`. +- For documentation creation or edits under `docs/` with locale parity, use the local skill: +`skills/docs-parity/SKILL.md`. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..2932c2f --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +docs: CODE_OF_CONDUCT.md. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/Makefile b/Makefile index 88ca178..8e85926 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,11 @@ TARGET_HEADER=@echo -e '===== \e[34m' $@ '\e[0m' YARN=@docker-compose run --rm node yarn +YARN_PLAYWRIGHT=@docker-compose run --rm playwright yarn +COVERAGE_PARTS_DIR=coverage/.parts +COVERAGE_UNIT_DIR=coverage/unit +COVERAGE_E2E_REACT_DIR=coverage/e2e-react +COVERAGE_E2E_VUE_DIR=coverage/e2e-vue +NYC_OUTPUT_DIR=.nyc_output .PHONY: up up: ## Starts storybook @@ -37,6 +43,32 @@ build: node_modules ## Creates a dist catalogue with library build $(TARGET_HEADER) $(YARN) build +.PHONY: storybook-build-test +storybook-build-test: node_modules ## Builds Storybook in --test mode for all UI workspaces + $(TARGET_HEADER) + $(YARN) workspace @modulify/m3-react storybook:build --test --quiet + $(YARN) workspace @modulify/m3-vue storybook:build --test --quiet + +.PHONY: storybook-build-test-react +storybook-build-test-react: node_modules ## Builds Storybook in --test mode for @modulify/m3-react + $(TARGET_HEADER) + $(YARN) workspace @modulify/m3-react storybook:build --test --quiet + +.PHONY: storybook-build-test-vue +storybook-build-test-vue: node_modules ## Builds Storybook in --test mode for @modulify/m3-vue + $(TARGET_HEADER) + $(YARN) workspace @modulify/m3-vue storybook:build --test --quiet + +.PHONY: test-smoke +test-smoke: node_modules ## Runs smoke tests for all UI workspaces + $(TARGET_HEADER) + $(YARN) test:smoke + +.PHONY: test-runtime-parity +test-runtime-parity: ## Checks Node/Yarn parity across docker services (node, storybook, playwright) + $(TARGET_HEADER) + ./runtime-parity.test.sh + .PHONY: husky husky: node_modules ## Adds husky git hooks with commit content checks @docker-compose run --rm node npx husky init @@ -66,6 +98,11 @@ tsc-vue: node_modules ## Runs type checks in @modulify/m3-vue $(TARGET_HEADER) $(YARN) workspace @modulify/m3-vue tsc +.PHONY: tsc-e2e +tsc-e2e: node_modules ## Runs type checks for Playwright Vitest configs + $(TARGET_HEADER) + $(YARN) exec tsc -p tsconfig.e2e.json --skipLibCheck + .PHONY: test test: node_modules ## Runs autotests $(TARGET_HEADER) @@ -79,15 +116,58 @@ else endif .PHONY: test-coverage -test-coverage: node_modules ## Runs autotests with --coverage +test-coverage: node_modules ## Runs merged coverage for unit and Playwright e2e tests + $(TARGET_HEADER) + @rm -rf coverage $(NYC_OUTPUT_DIR) + @mkdir -p $(COVERAGE_PARTS_DIR) $(NYC_OUTPUT_DIR) + $(YARN) test --coverage --coverage.provider=istanbul --coverage.reporter=json --coverage.reportsDirectory=$(COVERAGE_UNIT_DIR) + $(YARN_PLAYWRIGHT) test:e2e:coverage + @cp $(COVERAGE_UNIT_DIR)/coverage-final.json $(COVERAGE_PARTS_DIR)/unit.json + @cp $(COVERAGE_E2E_REACT_DIR)/coverage-final.json $(COVERAGE_PARTS_DIR)/e2e-react.json + @cp $(COVERAGE_E2E_VUE_DIR)/coverage-final.json $(COVERAGE_PARTS_DIR)/e2e-vue.json + @$(YARN) nyc merge $(COVERAGE_PARTS_DIR) $(NYC_OUTPUT_DIR)/coverage-final.json >/dev/null + $(YARN) nyc report + @$(YARN) nyc report --reporter=json-summary >/dev/null + @$(YARN) node --experimental-strip-types scripts/show-total-coverage.ts + +.PHONY: test-e2e +test-e2e: node_modules ## Runs Playwright-based e2e tests (Vitest browser mode) + $(TARGET_HEADER) + +ifdef cli + @$(YARN_PLAYWRIGHT) test:e2e $(cli) +else + @$(YARN_PLAYWRIGHT) test:e2e +endif + +.PHONY: test-e2e-react +test-e2e-react: node_modules ## Runs Playwright-based e2e tests for @modulify/m3-react + $(TARGET_HEADER) + +ifdef cli + @$(YARN_PLAYWRIGHT) workspace @modulify/m3-react test:e2e $(cli) +else + @$(YARN_PLAYWRIGHT) workspace @modulify/m3-react test:e2e +endif + +.PHONY: test-e2e-vue +test-e2e-vue: node_modules ## Runs Playwright-based e2e tests for @modulify/m3-vue $(TARGET_HEADER) - + ifdef cli - $(YARN) test --coverage $(cli) + @$(YARN_PLAYWRIGHT) workspace @modulify/m3-vue test:e2e $(cli) else - $(YARN) test --coverage + @$(YARN_PLAYWRIGHT) workspace @modulify/m3-vue test:e2e endif +.PHONY: test-e2e-stop +test-e2e-stop: ## Stops stuck Playwright E2E host processes and run containers + $(TARGET_HEADER) + @pkill -TERM -f "docker-compose run --rm playwright yarn test:[e]2e" || true + @pkill -TERM -f "docker-compose run --rm playwright yarn workspace @modulify/m3-react test:[e]2e" || true + @pkill -TERM -f "docker-compose run --rm playwright yarn workspace @modulify/m3-vue test:[e]2e" || true + @docker ps -q --filter "name=m3-web-playwright-run" | xargs -r docker rm -f + .PHONY: help help: ## Calls recipes list @cat $(MAKEFILE_LIST) | grep -e "^[-a-zA-Z_\.]*: *.*## *" | awk '\ diff --git a/README.md b/README.md index c5d1a2b..a0b1c60 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,19 @@ # m3-web -## Create yarn configuration +[![codecov](https://codecov.io/gh/modulify/m3-web/graph/badge.svg?branch=main)](https://codecov.io/gh/modulify/m3-web) -```bash -make .yarnrc.yml -``` +`m3-web` is a monorepo for a Material Design 3 component library for web. +The project builds a shared UI foundation for two platforms (`React` and `Vue`) with a focus on: +- consistent public API across platforms, +- verifiable quality (lint, tests, Storybook), +- practical engineering readiness for reuse and publishing. -## Installation +## Repository Contents -```bash -make node_modules -``` +- `m3-foundation`: shared styles, tokens, and base utilities. +- `m3-react`: React component implementation. +- `m3-vue`: Vue component implementation. -## Launch -```bash -make up -``` +## Participating -## Build -```bash -make build -``` - -## eslint -```bash -make eslint -``` - -## Tests -```bash -make test -``` \ No newline at end of file +Contribution docs: `docs/en/index.md` diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..2f31ae5 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,16 @@ +codecov: + require_ci_to_pass: true + +coverage: + precision: 2 + round: down + status: + project: + combined: + target: 73% + threshold: 0% + flags: + - combined + patch: off + +comment: false diff --git a/docker-compose.yml b/docker-compose.yml index 8622900..2f5e874 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,10 +1,15 @@ +x-node-image: &node_image node:24 + +x-node-common: &node_common + user: node + volumes: + - ./:/project + working_dir: /project + services: node: &node - image: node:24 - user: node - volumes: - - ./:/project - working_dir: /project + <<: *node_common + image: *node_image storybook-react: <<: *node @@ -33,3 +38,17 @@ services: traefik.http.routers.m3-vue-modulify.priority: 1 traefik.http.routers.m3-vue-modulify.service: m3-vue-modulify traefik.http.services.m3-vue-modulify.loadbalancer.server.port: '6006' + + playwright: + <<: *node_common + build: + context: . + dockerfile: docker/playwright/Dockerfile + args: + NODE_IMAGE: *node_image + environment: + PLAYWRIGHT_BROWSERS_PATH: '/ms-playwright' + CI: 'true' + shm_size: '1gb' + ipc: host + init: true diff --git a/docker/playwright/Dockerfile b/docker/playwright/Dockerfile new file mode 100644 index 0000000..70bc873 --- /dev/null +++ b/docker/playwright/Dockerfile @@ -0,0 +1,14 @@ +ARG NODE_IMAGE=node:24 +FROM ${NODE_IMAGE} + +USER root +WORKDIR /project + +ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright +ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0 + +RUN corepack enable \ + && npx -y playwright@1.58.2 install --with-deps chromium \ + && chown -R node:node /ms-playwright + +USER node diff --git a/docs/en/contributing.md b/docs/en/contributing.md new file mode 100644 index 0000000..d95bb34 --- /dev/null +++ b/docs/en/contributing.md @@ -0,0 +1,52 @@ +# Contributing Guide + +This document describes the practical contribution flow for `m3-web`. + +## Project Goal + +`m3-web` develops a Material Design 3 component library for web as a monorepo: +- shared foundation (`m3-foundation`), +- two platform implementations (`m3-react` and `m3-vue`), +- focus on predictable quality and API parity. + +## Quick Start + +```bash +make .yarnrc.yml +make node_modules +make test +``` + +## Core Commands + +- `make build`: build all workspaces. +- `make eslint`: run lint checks. +- `make test`: run unit/integration tests. +- `make storybook-build-test`: build Storybook in `--test` mode for React and Vue. +- `make test-smoke`: run smoke tests. +- `yarn tsc`: run package-level type checks for all workspaces. + +## Quality Gates (CI) + +CI runs: +- `eslint`, +- `tests`, +- `storybook-tests`: + `storybook:build --test` for React and Vue + accessibility smoke tests. + +Locally, it is recommended to run the same checks before pushing changes. + +## Repository Structure + +- `m3-foundation`: styles, tokens, and shared helpers. +- `m3-react`: React components, tests, and Storybook. +- `m3-vue`: Vue components, tests, and Storybook. + +## TSConfig Layering + +This project separates configs for editor DX and package-level type checks. +Details: `./tsconfig-layering.md`. + +In short: +- workspace `tsconfig.json`: for IDE, tests, and Storybook, +- workspace `tsconfig.tsc.json`: for CI/typecheck and publishable source. diff --git a/docs/en/index.md b/docs/en/index.md new file mode 100644 index 0000000..3d3428c --- /dev/null +++ b/docs/en/index.md @@ -0,0 +1,10 @@ +# Documentation + +## Contents + +- [Contributing Guide](./contributing.md) - Development workflow, core commands, and CI quality gates. +- [TSConfig Layering](./tsconfig-layering.md) - How TypeScript configs are split between editor DX and CI checks. + +## Translations + +- [Русский (ru)](../ru/index.md) diff --git a/docs/en/tsconfig-layering.md b/docs/en/tsconfig-layering.md new file mode 100644 index 0000000..9299184 --- /dev/null +++ b/docs/en/tsconfig-layering.md @@ -0,0 +1,31 @@ +# TSConfig Layering + +This repository uses separate TypeScript configs for editor-time DX and package-level CI type checks. + +## Layers + +1. `tsconfig.json` (root) +- Shared baseline compiler options for all workspaces. + +2. `m3-react/tsconfig.json` and `m3-vue/tsconfig.json` +- Editor-oriented workspace configs. +- Include `src`, `storybook`, and `tests`. +- Keep test globals (`vitest/globals`) where needed for IDE autocomplete in test files. + +3. `m3-react/tsconfig.tsc.json` and `m3-vue/tsconfig.tsc.json` +- CI/package typecheck configs. +- Include only publishable source (`src`, `types`, shims). +- Exclude `storybook` and `tests`. +- Reset `types` to `[]` to avoid pulling test-only globals into package checks. + +## Which Commands Use Which Config + +- `yarn workspace @modulify/m3-react tsc` -> `m3-react/tsconfig.tsc.json` +- `yarn workspace @modulify/m3-vue tsc` -> `m3-vue/tsconfig.tsc.json` +- `yarn tsc` (root) -> runs workspace `tsc` scripts above. + +## Rules of Thumb + +- If the goal is package correctness in CI/release, change `tsconfig.tsc.json`. +- If the goal is local editor/test/storybook experience, change workspace `tsconfig.json`. +- Keep root `tsconfig.json` as shared baseline only. diff --git a/docs/ru/contributing.md b/docs/ru/contributing.md new file mode 100644 index 0000000..8cad506 --- /dev/null +++ b/docs/ru/contributing.md @@ -0,0 +1,52 @@ +# Руководство по участию + +Этот документ описывает практический путь участия в разработке `m3-web`. + +## Цель проекта + +`m3-web` развивает компонентную библиотеку Material Design 3 для web в формате monorepo: +- общая база (`m3-foundation`), +- две платформенные реализации (`m3-react` и `m3-vue`), +- акцент на предсказуемое качество и API-паритет. + +## Быстрый старт + +```bash +make .yarnrc.yml +make node_modules +make test +``` + +## Основные команды + +- `make build`: собрать все workspaces. +- `make eslint`: прогнать линтер. +- `make test`: прогнать unit/integration тесты. +- `make storybook-build-test`: собрать Storybook в `--test` режиме для React и Vue. +- `make test-smoke`: прогнать smoke-тесты. +- `yarn tsc`: прогнать package-level typecheck по workspace-конфигациям. + +## Quality Gates (CI) + +В CI проверяются: +- `eslint`, +- `tests`, +- `storybook-tests`: + `storybook:build --test` для React и Vue + accessibility smoke-тесты. + +Локально желательно проходить те же проверки до отправки изменений. + +## Структура репозитория + +- `m3-foundation`: стили, токены, общие вспомогательные части. +- `m3-react`: React-компоненты, их тесты и Storybook. +- `m3-vue`: Vue-компоненты, их тесты и Storybook. + +## TSConfig layering + +В проекте разделены конфиги для editor DX и package-level typecheck. +Подробности: `./tsconfig-layering.md`. + +Коротко: +- workspace `tsconfig.json`: для IDE, тестов и Storybook, +- workspace `tsconfig.tsc.json`: для CI/typecheck и publishable source. diff --git a/docs/ru/index.md b/docs/ru/index.md new file mode 100644 index 0000000..6a36c7c --- /dev/null +++ b/docs/ru/index.md @@ -0,0 +1,6 @@ +# Документация + +## Содержание + +- [Руководство по участию](./contributing.md) - Процесс разработки, ключевые команды и проверки в CI. +- [Слои TSConfig](./tsconfig-layering.md) - Разделение TypeScript-конфигов для IDE и package-level typecheck. diff --git a/docs/ru/tsconfig-layering.md b/docs/ru/tsconfig-layering.md new file mode 100644 index 0000000..b4c5638 --- /dev/null +++ b/docs/ru/tsconfig-layering.md @@ -0,0 +1,31 @@ +# Слои TSConfig + +В этом репозитории TypeScript-конфиги разделены для editor DX и package-level typecheck в CI. + +## Слои + +1. `tsconfig.json` (корень) +- Общая базовая конфигурация для всех workspaces. + +2. `m3-react/tsconfig.json` и `m3-vue/tsconfig.json` +- Конфиги для редактора и локальной разработки. +- Включают `src`, `storybook` и `tests`. +- Сохраняют test globals (`vitest/globals`) для автодополнения в тестовых файлах. + +3. `m3-react/tsconfig.tsc.json` и `m3-vue/tsconfig.tsc.json` +- Конфиги для CI/package typecheck. +- Включают только публикуемые исходники (`src`, `types`, shims). +- Исключают `storybook` и `tests`. +- Сбрасывают `types` в `[]`, чтобы test-only globals не попадали в package-проверки. + +## Какие Команды Используют Какие Конфиги + +- `yarn workspace @modulify/m3-react tsc` -> `m3-react/tsconfig.tsc.json` +- `yarn workspace @modulify/m3-vue tsc` -> `m3-vue/tsconfig.tsc.json` +- `yarn tsc` (root) -> запускает workspace-скрипты `tsc` выше. + +## Правила Практики + +- Если цель — корректность пакета в CI/release, меняется `tsconfig.tsc.json`. +- Если цель — удобство IDE/тестов/Storybook, меняется workspace `tsconfig.json`. +- Корневой `tsconfig.json` остаётся только общей базой. diff --git a/m3-react/package.json b/m3-react/package.json index 290766a..b337c0e 100644 --- a/m3-react/package.json +++ b/m3-react/package.json @@ -25,6 +25,9 @@ "eslint": "eslint ./src ./storybook ./tests ./types", "storybook": "storybook dev -c storybook -p 6006 --no-open", "storybook:build": "storybook build -c storybook -o dist-storybook", + "test:smoke": "VITEST_STORYBOOK=false vitest run --config vitest.config.smoke.ts", + "test:e2e": "vitest run --config vitest.config.e2e.ts", + "test:e2e:coverage": "vitest run --config vitest.config.e2e.ts --coverage --coverage.provider=istanbul --coverage.reporter=json", "test": "vitest run", "tsc": "tsc --noEmit -p tsconfig.tsc.json" }, @@ -62,6 +65,8 @@ "@typescript-eslint/eslint-plugin": "^8.56.0", "@typescript-eslint/parser": "^8.56.0", "@vitejs/plugin-react": "^5.1.4", + "@vitest/browser": "^4.0.18", + "@vitest/browser-playwright": "^4.0.18", "eslint": "^9.39.3", "eslint-plugin-import": "^2.32.0", "eslint-plugin-react": "^7.37.5", @@ -70,6 +75,7 @@ "flag-icons": "^7.5.0", "globals": "^17.3.0", "jsdom": "^28.1.0", + "playwright": "^1.55.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-transition-group": "^4.4.5", diff --git a/m3-react/storybook/main.ts b/m3-react/storybook/main.ts index 5db2e71..f07f9ab 100644 --- a/m3-react/storybook/main.ts +++ b/m3-react/storybook/main.ts @@ -27,9 +27,6 @@ const config: StorybookConfig = { }, }, }, - docs: { - autodocs: 'tag', - }, framework: { name: '@storybook/react-vite', options: {}, diff --git a/m3-react/storybook/preview.ts b/m3-react/storybook/preview.ts index f3c356f..b613a5c 100644 --- a/m3-react/storybook/preview.ts +++ b/m3-react/storybook/preview.ts @@ -83,6 +83,15 @@ installThemeSync() export default { parameters: { + a11y: { + test: 'error', + options: { + runOnly: { + type: 'tag', + values: ['wcag2a', 'wcag2aa'], + }, + }, + }, backgrounds: { disable: true }, controls: { matchers: { diff --git a/m3-react/tests/M3Popper.e2e.tsx b/m3-react/tests/M3Popper.e2e.tsx new file mode 100644 index 0000000..f82c1ea --- /dev/null +++ b/m3-react/tests/M3Popper.e2e.tsx @@ -0,0 +1,130 @@ +import type { + M3PopperMethods, +} from '@/components/popper' + +import { + act, + render, + waitFor, +} from '@testing-library/react' + +import { createRef } from 'react' + +import { M3Popper } from '@/components/popper' + +const rect = (x: number, y: number, width: number, height: number): DOMRect => ( + DOMRect.fromRect({ + x, + y, + width, + height, + }) +) + +const expectedX = (popper: HTMLElement, offsetCrossAxis = 0) => { + const { width } = popper.getBoundingClientRect() + return Math.round(100 + 20 - width / 2 + offsetCrossAxis) +} + +const expectTransform = (popper: HTMLElement, x: number, y: number) => { + expect(popper.style.transform).toMatch(new RegExp(`^translate3d\\(${x}px,\\s*${y}px,\\s*0px\\)$`)) +} + +const waitForPopper = async () => { + await waitFor(() => { + expect(document.body.querySelector('.m3-popper')).not.toBeNull() + }) + + return document.body.querySelector('.m3-popper') as HTMLElement +} + +describe('m3-react/popper e2e', () => { + let target: HTMLButtonElement | null = null + let unmount: null | (() => void) = null + + afterEach(() => { + unmount?.() + unmount = null + target?.remove() + target = null + vi.restoreAllMocks() + }) + + test('applies bottom placement geometry with main axis offset', async () => { + target = document.createElement('button') + document.body.append(target) + + const popperRef = createRef() + + const mounted = render( + +
+ Popper content +
+
+ ) + unmount = mounted.unmount + + const popper = await waitForPopper() + + vi.spyOn(target, 'getBoundingClientRect').mockReturnValue(rect(100, 50, 40, 20)) + const x = expectedX(popper) + + await act(async () => { + await popperRef.current?.adjust() + }) + + await waitFor(() => { + expectTransform(popper, x, 80) + expect(popper.style.position).toBe('absolute') + }) + }) + + test('applies cross axis offset for bottom placement', async () => { + target = document.createElement('button') + document.body.append(target) + + const popperRef = createRef() + + const mounted = render( + +
+ Popper content +
+
+ ) + unmount = mounted.unmount + + const popper = await waitForPopper() + + vi.spyOn(target, 'getBoundingClientRect').mockReturnValue(rect(100, 50, 40, 20)) + const x = expectedX(popper, 7) + + await act(async () => { + await popperRef.current?.adjust() + }) + + await waitFor(() => { + expectTransform(popper, x, 70) + expect(popper.style.position).toBe('absolute') + }) + }) +}) diff --git a/m3-react/tests/storybook/a11y.smoke.ts b/m3-react/tests/storybook/a11y.smoke.ts new file mode 100644 index 0000000..4fa1507 --- /dev/null +++ b/m3-react/tests/storybook/a11y.smoke.ts @@ -0,0 +1,54 @@ +import * as a11yAddon from '@storybook/addon-a11y/preview' +import { + composeStories, + setProjectAnnotations, +} from '@storybook/react' + +import preview from '../../storybook/preview' + +if (typeof globalThis.ResizeObserver === 'undefined') { + class ResizeObserverMock { + observe (): void {} + + unobserve (): void {} + + disconnect (): void {} + } + + ;(globalThis as unknown as { ResizeObserver: typeof ResizeObserver }).ResizeObserver = + ResizeObserverMock as unknown as typeof ResizeObserver +} + +const projectAnnotations = setProjectAnnotations([ + a11yAddon, + preview, +]) + +const storyModules = import.meta.glob('../../storybook/components/*.stories.tsx', { + eager: true, +}) + +type RunnableStory = { + run: () => Promise +} + +type ComposableStoriesModule = Parameters[0] + +const stories = Object.entries(storyModules).flatMap(([modulePath, moduleExports]) => { + const composedStories = composeStories(moduleExports as ComposableStoriesModule, projectAnnotations) + + return Object.entries(composedStories).map(([storyName, story]) => ({ + id: `${modulePath}:${storyName}`, + story: story as RunnableStory, + })) +}) + +describe('m3-react/storybook a11y smoke', () => { + test('collects stories for smoke checks', () => { + expect(stories.length).toBeGreaterThan(0) + }) + + test.each(stories)('$id', async ({ story }) => { + await story.run() + }) +}) diff --git a/m3-react/tsconfig.json b/m3-react/tsconfig.json index c130e50..dd70f37 100644 --- a/m3-react/tsconfig.json +++ b/m3-react/tsconfig.json @@ -1,7 +1,8 @@ { + "extends": "../tsconfig.json", "compilerOptions": { "baseUrl": "./", - "esModuleInterop": true, + "moduleResolution": "bundler", "jsx": "react-jsx", "lib": [ "DOM", @@ -9,15 +10,14 @@ "ES2017", "esnext.disposable" ], - "module": "esnext", - "moduleResolution": "node", "paths": { "@/*": ["./src/*"], "~types/*": ["./types/*"] }, - "resolveJsonModule": true, - "target": "ES2017", - "types": ["vitest/globals"] + "types": [ + "vitest/globals", + "vite/client" + ] }, "include": [ "shims-*.d.ts", @@ -25,6 +25,7 @@ "src/**/*.tsx", "storybook/**/*.ts", "storybook/**/*.tsx", + "tests/**/*.ts", "tests/**/*.tsx" ] } diff --git a/m3-react/tsconfig.tsc.json b/m3-react/tsconfig.tsc.json index ef98197..14dc5cc 100644 --- a/m3-react/tsconfig.tsc.json +++ b/m3-react/tsconfig.tsc.json @@ -1,7 +1,8 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "moduleResolution": "bundler" + "moduleResolution": "bundler", + "types": [] }, "include": [ "shims-*.d.ts", diff --git a/m3-react/vitest.config.e2e.ts b/m3-react/vitest.config.e2e.ts new file mode 100644 index 0000000..30e89f2 --- /dev/null +++ b/m3-react/vitest.config.e2e.ts @@ -0,0 +1,39 @@ +import { + defineConfig, + mergeConfig, +} from 'vitest/config' + +import { fileURLToPath } from 'node:url' + +import { playwright } from '@vitest/browser-playwright' + +import viteConfig from './vite.config' + +const workspaceRoot = fileURLToPath(new URL('./', import.meta.url)) +const browserProvider = playwright({ + launchOptions: { + // Avoid headless_shell instability in Linux containers. + channel: 'chromium', + }, +}) + +export default mergeConfig(viteConfig, defineConfig({ + root: workspaceRoot, + test: { + name: 'm3-react-e2e', + globals: true, + include: [ + 'tests/**/*.e2e.tsx', + ], + browser: { + enabled: true, + provider: browserProvider, + headless: true, + instances: [ + { + browser: 'chromium', + }, + ], + }, + }, +})) diff --git a/m3-react/vitest.config.smoke.ts b/m3-react/vitest.config.smoke.ts new file mode 100644 index 0000000..cbac0ff --- /dev/null +++ b/m3-react/vitest.config.smoke.ts @@ -0,0 +1,15 @@ +import { + defineConfig, + mergeConfig, +} from 'vitest/config' + +import vitestConfig from './vitest.config' + +export default mergeConfig(vitestConfig, defineConfig({ + test: { + name: 'm3-react-smoke', + include: [ + 'tests/**/*.smoke.ts', + ], + }, +})) diff --git a/m3-vue/package.json b/m3-vue/package.json index 0462c8d..32cc8a3 100644 --- a/m3-vue/package.json +++ b/m3-vue/package.json @@ -25,6 +25,9 @@ "eslint": "eslint ./src ./storybook ./tests ./types", "storybook": "storybook dev -c storybook -p 6006 --no-open", "storybook:build": "storybook build -c storybook -o dist-storybook", + "test:smoke": "VITEST_STORYBOOK=false vitest run --config vitest.config.smoke.ts", + "test:e2e": "vitest run --config vitest.config.e2e.ts", + "test:e2e:coverage": "vitest run --config vitest.config.e2e.ts --coverage --coverage.provider=istanbul --coverage.reporter=json", "test": "vitest run", "tsc": "vue-tsc --noEmit -p tsconfig.tsc.json" }, @@ -56,6 +59,8 @@ "@typescript-eslint/eslint-plugin": "^8.56.0", "@typescript-eslint/parser": "^8.56.0", "@vitejs/plugin-vue": "^6.0.4", + "@vitest/browser": "^4.0.18", + "@vitest/browser-playwright": "^4.0.18", "@vue/compiler-sfc": "^3.5.28", "@vue/language-server": "^3.2.5", "eslint": "^9.39.3", @@ -65,6 +70,7 @@ "flag-icons": "^7.5.0", "globals": "^17.3.0", "jsdom": "^28.1.0", + "playwright": "^1.55.0", "react": "^18.3.1", "react-dom": "^18.3.1", "sass": "^1.97.3", diff --git a/m3-vue/storybook/preview.ts b/m3-vue/storybook/preview.ts index aa021b4..3d7f251 100644 --- a/m3-vue/storybook/preview.ts +++ b/m3-vue/storybook/preview.ts @@ -83,6 +83,15 @@ installThemeSync() export default { parameters: { + a11y: { + test: 'error', + options: { + runOnly: { + type: 'tag', + values: ['wcag2a', 'wcag2aa'], + }, + }, + }, backgrounds: { disable: true }, controls: { matchers: { diff --git a/m3-vue/tests/M3Checkbox.test.ts b/m3-vue/tests/M3Checkbox.test.ts index c052517..95e1942 100644 --- a/m3-vue/tests/M3Checkbox.test.ts +++ b/m3-vue/tests/M3Checkbox.test.ts @@ -10,11 +10,11 @@ describe('m3-vue/checkbox', () => { test('reflects aria state and emits scalar values', async () => { const view = render(M3Checkbox, { props: { - model: false, + model: 'no', trueValue: 'yes', falseValue: 'no', invalid: true, - }, + } as Record, }) const input = screen.getByRole('checkbox') as HTMLInputElement diff --git a/m3-vue/tests/M3Popper.e2e.ts b/m3-vue/tests/M3Popper.e2e.ts new file mode 100644 index 0000000..0d3d061 --- /dev/null +++ b/m3-vue/tests/M3Popper.e2e.ts @@ -0,0 +1,187 @@ +import type { App } from 'vue' + +import { + createApp, + h, + nextTick, + ref, +} from 'vue' + +import { M3Popper } from '@/components/popper' + +const rect = (x: number, y: number, width: number, height: number): DOMRect => ( + DOMRect.fromRect({ + x, + y, + width, + height, + }) +) + +const parseTransform = (popper: HTMLElement) => { + const match = popper.style.transform.match(/translate3d\(([-\d.]+)px,\s*([-\d.]+)px,\s*0px\)/) + if (!match) { + throw new Error(`Unexpected transform: ${popper.style.transform}`) + } + + return { + x: Number(match[1]), + y: Number(match[2]), + } +} + +const expectY = (popper: HTMLElement, expectedY: number) => { + const { y } = parseTransform(popper) + expect(y).toBe(expectedY) +} + +const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)) + +const waitFor = async (assertion: () => void, timeoutMs = 1200) => { + const startedAt = Date.now() + let lastError: unknown + + while (Date.now() - startedAt < timeoutMs) { + try { + assertion() + return + } catch (error) { + lastError = error + await delay(10) + } + } + + throw lastError ?? new Error('waitFor timeout') +} + +const waitForPopper = async () => { + let popper: HTMLElement | null = null + + await waitFor(() => { + popper = document.body.querySelector('.m3-popper') as HTMLElement | null + expect(popper).not.toBeNull() + }) + + return popper as HTMLElement +} + +type MountResult = { + app: App; + mountPoint: HTMLDivElement; + setProps: (nextProps: Record) => Promise; +} + +type VueComponentLike = Parameters[0] + +const createProps = (target: HTMLElement) => ref>({ + target: () => target, + shown: true, + placement: 'bottom', + overflow: [], + offsetMainAxis: 0, + offsetCrossAxis: 0, + detachTimeout: null, +}) + +const createSetProps = (props: ReturnType) => { + return async (nextProps: Record) => { + props.value = { + ...props.value, + ...nextProps, + } + + await nextTick() + await delay(0) + } +} + +const mountPopper = (target: HTMLElement): MountResult => { + const mountPoint = document.createElement('div') + document.body.append(mountPoint) + + const props = createProps(target) + const setProps = createSetProps(props) + + const app = createApp({ + setup () { + return () => h(M3Popper as VueComponentLike, props.value, { + default: () => h('div', 'Popper content'), + }) + }, + }) + + app.mount(mountPoint) + + return { + app, + mountPoint, + setProps, + } +} + +const createTarget = () => { + const target = document.createElement('button') + document.body.append(target) + return target +} + +const setupGeometryCase = async (mounted: MountResult, target: HTMLButtonElement) => { + const popper = await waitForPopper() + + vi.spyOn(target, 'getBoundingClientRect').mockReturnValue(rect(100, 50, 40, 20)) + return popper +} + +// eslint-disable-next-line max-lines-per-function +describe('m3-vue/popper e2e', () => { + let target: HTMLButtonElement | null = null + let mounted: MountResult | null = null + beforeEach(() => { + target = createTarget() + mounted = mountPopper(target) + }) + afterEach(() => { + mounted?.app.unmount() + mounted?.mountPoint.remove() + mounted = null + target?.remove() + target = null + vi.restoreAllMocks() + }) + test('applies bottom placement geometry with main axis offset', async () => { + const popper = await setupGeometryCase(mounted as MountResult, target as HTMLButtonElement) + + await (mounted as MountResult).setProps({ + offsetMainAxis: 10, + }) + + await waitFor(() => { + expectY(popper, 80) + expect(popper.style.position).toBe('absolute') + }) + }) + test('applies cross axis offset for bottom placement', async () => { + const popper = await setupGeometryCase(mounted as MountResult, target as HTMLButtonElement) + + await (mounted as MountResult).setProps({ + offsetCrossAxis: 0, + }) + + let x0 = 0 + await waitFor(() => { + x0 = parseTransform(popper).x + expectY(popper, 70) + }) + + await (mounted as MountResult).setProps({ + offsetCrossAxis: 7, + }) + + await waitFor(() => { + const { x, y } = parseTransform(popper) + expect(y).toBe(70) + expect(Math.round(x - x0)).toBe(7) + expect(popper.style.position).toBe('absolute') + }) + }) +}) diff --git a/m3-vue/tests/storybook/a11y.smoke.ts b/m3-vue/tests/storybook/a11y.smoke.ts new file mode 100644 index 0000000..54f9cd1 --- /dev/null +++ b/m3-vue/tests/storybook/a11y.smoke.ts @@ -0,0 +1,54 @@ +import * as a11yAddon from '@storybook/addon-a11y/preview' +import { + composeStories, + setProjectAnnotations, +} from '@storybook/vue3' + +import preview from '../../storybook/preview' + +if (typeof globalThis.ResizeObserver === 'undefined') { + class ResizeObserverMock { + observe (): void {} + + unobserve (): void {} + + disconnect (): void {} + } + + ;(globalThis as unknown as { ResizeObserver: typeof ResizeObserver }).ResizeObserver = + ResizeObserverMock as unknown as typeof ResizeObserver +} + +const projectAnnotations = setProjectAnnotations([ + a11yAddon, + preview, +]) + +const storyModules = import.meta.glob('../../storybook/components/*.stories.ts', { + eager: true, +}) + +type RunnableStory = { + run: () => Promise +} + +type ComposableStoriesModule = Parameters[0] + +const stories = Object.entries(storyModules).flatMap(([modulePath, moduleExports]) => { + const composedStories = composeStories(moduleExports as ComposableStoriesModule, projectAnnotations) + + return Object.entries(composedStories).map(([storyName, story]) => ({ + id: `${modulePath}:${storyName}`, + story: story as unknown as RunnableStory, + })) +}) + +describe('m3-vue/storybook a11y smoke', () => { + test('collects stories for smoke checks', () => { + expect(stories.length).toBeGreaterThan(0) + }) + + test.each(stories)('$id', async ({ story }) => { + await story.run() + }) +}) diff --git a/m3-vue/tsconfig.json b/m3-vue/tsconfig.json index ece979d..8485458 100644 --- a/m3-vue/tsconfig.json +++ b/m3-vue/tsconfig.json @@ -1,30 +1,21 @@ { + "extends": "../tsconfig.json", "compilerOptions": { "baseUrl": "./", - "esModuleInterop": true, + "moduleResolution": "bundler", "lib": [ "DOM", "DOM.Iterable", "ES2017", "esnext.disposable" ], - "module": "esnext", - "moduleResolution": "node", "paths": { "@/*": ["./src/*"], "~types/*": ["./types/*"] }, - "resolveJsonModule": true, - "target": "ES2017", "types": [ - "@vue/compiler-core/dist/compiler-core", - "@vue/compiler-dom/dist/compiler-dom", - "@vue/compiler-sfc/dist/compiler-sfc", - "@vue/compiler-ssr/dist/compiler-ssr", - "@vue/reactivity/dist/reactivity", - "@vue/runtime-core/dist/runtime-core", - "@vue/runtime-dom/dist/runtime-dom", - "vitest/globals" + "vitest/globals", + "vite/client" ] }, "include": [ diff --git a/m3-vue/tsconfig.tsc.json b/m3-vue/tsconfig.tsc.json index dfc6e37..6835044 100644 --- a/m3-vue/tsconfig.tsc.json +++ b/m3-vue/tsconfig.tsc.json @@ -2,9 +2,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "moduleResolution": "bundler", - "types": [ - "vitest/globals" - ] + "types": [] }, "include": [ "shims-*.d.ts", diff --git a/m3-vue/vitest.config.e2e.ts b/m3-vue/vitest.config.e2e.ts new file mode 100644 index 0000000..a7c10ca --- /dev/null +++ b/m3-vue/vitest.config.e2e.ts @@ -0,0 +1,39 @@ +import { + defineProject, + mergeConfig, +} from 'vitest/config' + +import { fileURLToPath } from 'node:url' + +import { playwright } from '@vitest/browser-playwright' + +import viteConfig from './vite.config' + +const workspaceRoot = fileURLToPath(new URL('./', import.meta.url)) +const browserProvider = playwright({ + launchOptions: { + // Avoid headless_shell instability in Linux containers. + channel: 'chromium', + }, +}) + +export default mergeConfig(viteConfig, defineProject({ + root: workspaceRoot, + test: { + name: 'm3-vue-e2e', + globals: true, + include: [ + 'tests/**/*.e2e.ts', + ], + browser: { + enabled: true, + provider: browserProvider, + headless: true, + instances: [ + { + browser: 'chromium', + }, + ], + }, + }, +})) diff --git a/m3-vue/vitest.config.smoke.ts b/m3-vue/vitest.config.smoke.ts new file mode 100644 index 0000000..4790465 --- /dev/null +++ b/m3-vue/vitest.config.smoke.ts @@ -0,0 +1,15 @@ +import { + defineProject, + mergeConfig, +} from 'vitest/config' + +import vitestConfig from './vitest.config' + +export default mergeConfig(vitestConfig, defineProject({ + test: { + name: 'm3-vue-smoke', + include: [ + 'tests/**/*.smoke.ts', + ], + }, +})) diff --git a/package.json b/package.json index e670754..8bdd48e 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,16 @@ "build": "yarn workspaces foreach -W run build", "commitlint": "commitlint --edit", "eslint": "yarn workspaces foreach -W run eslint", + "test:e2e:react": "yarn workspace @modulify/m3-react test:e2e", + "test:e2e:vue": "yarn workspace @modulify/m3-vue test:e2e", + "test:e2e": "yarn test:e2e:react && yarn test:e2e:vue", + "test:e2e:coverage:react": "yarn workspace @modulify/m3-react test:e2e:coverage --coverage.reportsDirectory=../coverage/e2e-react", + "test:e2e:coverage:vue": "yarn workspace @modulify/m3-vue test:e2e:coverage --coverage.reportsDirectory=../coverage/e2e-vue", + "test:e2e:coverage": "yarn test:e2e:coverage:react && yarn test:e2e:coverage:vue", + "test:smoke": "yarn workspace @modulify/m3-react test:smoke && yarn workspace @modulify/m3-vue test:smoke", "test": "vitest run", "tsc": "yarn workspaces foreach -W run tsc", + "tsc:e2e": "tsc -p tsconfig.e2e.json --skipLibCheck", "tsc:foundation": "yarn workspace @modulify/m3-foundation tsc", "tsc:react": "yarn workspace @modulify/m3-react tsc", "tsc:vue": "yarn workspace @modulify/m3-vue tsc" @@ -21,9 +29,14 @@ "devDependencies": { "@commitlint/cli": "^20.4.2", "@commitlint/config-conventional": "^20.4.2", + "@vitest/browser": "^4.0.18", + "@vitest/browser-playwright": "^4.0.18", "@vitest/coverage-istanbul": "^4.0.18", "@vitest/ui": "4.0.18", + "canvas": "^3.2.1", "jsdom": "^28.1.0", + "nyc": "^17.1.0", + "playwright": "^1.55.0", "typescript": "~5.9.3", "vitest": "^4.0.18" }, diff --git a/runtime-parity.test.sh b/runtime-parity.test.sh new file mode 100755 index 0000000..98690cc --- /dev/null +++ b/runtime-parity.test.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env sh + +set -eu + +if command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1; then + DC_CMD='docker compose' +elif command -v docker-compose >/dev/null 2>&1; then + DC_CMD='docker-compose' +else + echo "Error: neither 'docker compose' nor 'docker-compose' is available." >&2 + exit 1 +fi + +compose() { + # shellcheck disable=SC2086 + $DC_CMD "$@" +} + +version_for() { + service="$1" + binary="$2" + + compose run --rm "$service" "$binary" --version | awk 'END { print }' | tr -d '\r' +} + +expected_node="$(version_for node node)" +expected_yarn="$(version_for node yarn)" + +for service in node storybook-react storybook-vue playwright; do + node_version="$(version_for "$service" node)" + yarn_version="$(version_for "$service" yarn)" + + if [ "$node_version" != "$expected_node" ]; then + echo "Node mismatch in $service: $node_version (expected $expected_node)" + exit 1 + fi + + if [ "$yarn_version" != "$expected_yarn" ]; then + echo "Yarn mismatch in $service: $yarn_version (expected $expected_yarn)" + exit 1 + fi + + echo "$service: node=$node_version yarn=$yarn_version" +done diff --git a/scripts/show-total-coverage.ts b/scripts/show-total-coverage.ts new file mode 100644 index 0000000..67e8b04 --- /dev/null +++ b/scripts/show-total-coverage.ts @@ -0,0 +1,36 @@ +import { readFileSync } from 'node:fs' + +type CoverageMetric = { + covered: number; + total: number; +} + +type CoverageSummary = { + total: { + statements: CoverageMetric; + branches: CoverageMetric; + functions: CoverageMetric; + lines: CoverageMetric; + }; +} + +const summaryPath = process.argv[2] ?? 'coverage/coverage-summary.json' +const summary = JSON.parse(readFileSync(summaryPath, 'utf8')) as CoverageSummary + +const totalCovered = ( + summary.total.statements.covered + + summary.total.branches.covered + + summary.total.functions.covered + + summary.total.lines.covered +) + +const totalChecks = ( + summary.total.statements.total + + summary.total.branches.total + + summary.total.functions.total + + summary.total.lines.total +) + +const percentage = totalChecks === 0 ? 0 : (totalCovered / totalChecks) * 100 + +console.log(`Total coverage: ${percentage.toFixed(2)}%`) diff --git a/skills/docs-parity/SKILL.md b/skills/docs-parity/SKILL.md new file mode 100644 index 0000000..de72186 --- /dev/null +++ b/skills/docs-parity/SKILL.md @@ -0,0 +1,57 @@ +--- +name: docs-parity +description: Use this skill when creating or editing documentation files under docs/. It enforces English-first changes, locale translation parity, adding missing translations, and index.md updates per locale with short summaries. +--- + +# Docs Parity + +## When To Use +Use this skill when the task creates or edits documents under `docs/`. + +## When Not To Use +- Changes outside `docs/`. + +## Required Rules +- English under `docs/en/` is the source of truth. +- For edits: update the English version first, then update localized versions. +- For new docs: create English first, then create localized versions. +- Canonical source path is under `docs/en/`. +- Existing locale directories under `docs/` are discovered first, then translations are created for each locale. +- If a document is found without translation for an existing locale, add the missing translation. +- Each locale keeps the same relative document path. +- Each locale `index.md` must include a link to the local document with a short one-line summary. +- `docs/en/index.md` keeps the `Translations` section with links to locale indexes. + +## Workflow +1. Discover locale directories under `docs/`: +```bash +find docs -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | sort +``` +2. Determine relative doc path (for example `guides/component-parity.md`). +If task starts from non-English locale, map to canonical path: `docs/en/`. +3. Apply content changes to English source first: +`docs/en/`. +4. For each discovered locale `L`: + - ensure file exists at `docs/L/`; + - if `L` is not `en`, update translation from English source; + - if missing, create translation. +5. Update `docs/L/index.md` for each locale: + - add document under `Contents` / `Содержание`; + - link format: + `./`; + - add a short summary on the same line. +6. Ensure `docs/en/index.md` `Translations` section links to available locale indexes. +7. Validate links and parity: + - every locale has the document file; + - every locale index links to its local file; + - no duplicated bullets in indexes. + +## Index Entry Format +- English: +`- [Title](./relative/path.md) - Short summary.` +- Russian: +`- [Заголовок](./relative/path.md) - Краткая сводка.` + +## Practical Notes +- Keep summaries concise and content-focused. +- Keep document structure aligned across locales (sections, order, intent). diff --git a/tsconfig.e2e.json b/tsconfig.e2e.json new file mode 100644 index 0000000..a310b6b --- /dev/null +++ b/tsconfig.e2e.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "moduleResolution": "bundler", + "noEmit": true + }, + "include": [ + "vitest.config.e2e.ts", + "m3-react/vitest.config.e2e.ts", + "m3-vue/vitest.config.e2e.ts" + ] +} diff --git a/vitest.config.e2e.ts b/vitest.config.e2e.ts new file mode 100644 index 0000000..825206e --- /dev/null +++ b/vitest.config.e2e.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + projects: [ + './m3-react/vitest.config.e2e.ts', + './m3-vue/vitest.config.e2e.ts', + ], + }, +}) diff --git a/yarn.lock b/yarn.lock index 7619e4b..9b88e0c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1450,7 +1450,20 @@ __metadata: languageName: node linkType: hard -"@istanbuljs/schema@npm:^0.1.3": +"@istanbuljs/load-nyc-config@npm:^1.0.0": + version: 1.1.0 + resolution: "@istanbuljs/load-nyc-config@npm:1.1.0" + dependencies: + camelcase: "npm:^5.3.1" + find-up: "npm:^4.1.0" + get-package-type: "npm:^0.1.0" + js-yaml: "npm:^3.13.1" + resolve-from: "npm:^5.0.0" + checksum: 10c0/dd2a8b094887da5a1a2339543a4933d06db2e63cbbc2e288eb6431bd832065df0c099d091b6a67436e71b7d6bf85f01ce7c15f9253b4cbebcc3b9a496165ba42 + languageName: node + linkType: hard + +"@istanbuljs/schema@npm:^0.1.2, @istanbuljs/schema@npm:^0.1.3": version: 0.1.3 resolution: "@istanbuljs/schema@npm:0.1.3" checksum: 10c0/61c5286771676c9ca3eb2bd8a7310a9c063fb6e0e9712225c8471c582d157392c88f5353581c8c9adbe0dff98892317d2fdfc56c3499aa42e0194405206a963a @@ -1644,6 +1657,8 @@ __metadata: "@typescript-eslint/eslint-plugin": "npm:^8.56.0" "@typescript-eslint/parser": "npm:^8.56.0" "@vitejs/plugin-react": "npm:^5.1.4" + "@vitest/browser": "npm:^4.0.18" + "@vitest/browser-playwright": "npm:^4.0.18" eslint: "npm:^9.39.3" eslint-plugin-import: "npm:^2.32.0" eslint-plugin-react: "npm:^7.37.5" @@ -1653,6 +1668,7 @@ __metadata: globals: "npm:^17.3.0" jsdom: "npm:^28.1.0" lodash.isequal: "npm:^4.5.0" + playwright: "npm:^1.55.0" react: "npm:^18.2.0" react-dom: "npm:^18.2.0" react-transition-group: "npm:^4.4.5" @@ -1700,6 +1716,8 @@ __metadata: "@typescript-eslint/eslint-plugin": "npm:^8.56.0" "@typescript-eslint/parser": "npm:^8.56.0" "@vitejs/plugin-vue": "npm:^6.0.4" + "@vitest/browser": "npm:^4.0.18" + "@vitest/browser-playwright": "npm:^4.0.18" "@vue/compiler-sfc": "npm:^3.5.28" "@vue/language-server": "npm:^3.2.5" eslint: "npm:^9.39.3" @@ -1710,6 +1728,7 @@ __metadata: globals: "npm:^17.3.0" jsdom: "npm:^28.1.0" lodash.isequal: "npm:^4.5.0" + playwright: "npm:^1.55.0" react: "npm:^18.3.1" react-dom: "npm:^18.3.1" sass: "npm:^1.97.3" @@ -1737,9 +1756,14 @@ __metadata: dependencies: "@commitlint/cli": "npm:^20.4.2" "@commitlint/config-conventional": "npm:^20.4.2" + "@vitest/browser": "npm:^4.0.18" + "@vitest/browser-playwright": "npm:^4.0.18" "@vitest/coverage-istanbul": "npm:^4.0.18" "@vitest/ui": "npm:4.0.18" + canvas: "npm:^3.2.1" jsdom: "npm:^28.1.0" + nyc: "npm:^17.1.0" + playwright: "npm:^1.55.0" typescript: "npm:~5.9.3" vitest: "npm:^4.0.18" languageName: unknown @@ -3001,6 +3025,41 @@ __metadata: languageName: node linkType: hard +"@vitest/browser-playwright@npm:^4.0.18": + version: 4.0.18 + resolution: "@vitest/browser-playwright@npm:4.0.18" + dependencies: + "@vitest/browser": "npm:4.0.18" + "@vitest/mocker": "npm:4.0.18" + tinyrainbow: "npm:^3.0.3" + peerDependencies: + playwright: "*" + vitest: 4.0.18 + peerDependenciesMeta: + playwright: + optional: false + checksum: 10c0/505fafe6f957d020b74914ed328de57cba0be65ff82810da85297523776a0d7389669660e58734a416fc09ce262632b4d2cf257a9e8ab1115b695d133bba7bb5 + languageName: node + linkType: hard + +"@vitest/browser@npm:4.0.18, @vitest/browser@npm:^4.0.18": + version: 4.0.18 + resolution: "@vitest/browser@npm:4.0.18" + dependencies: + "@vitest/mocker": "npm:4.0.18" + "@vitest/utils": "npm:4.0.18" + magic-string: "npm:^0.30.21" + pixelmatch: "npm:7.1.0" + pngjs: "npm:^7.0.0" + sirv: "npm:^3.0.2" + tinyrainbow: "npm:^3.0.3" + ws: "npm:^8.18.3" + peerDependencies: + vitest: 4.0.18 + checksum: 10c0/6b7bda92fa2e8c68de3e51c97322161484c3f1dd7a7417cdeabb4f1d98eab7dba96c156ac4282ea537c58d55cc0e5959abb4b9d90d3823b3cc3071c3f7460633 + languageName: node + linkType: hard + "@vitest/coverage-istanbul@npm:^4.0.18": version: 4.0.18 resolution: "@vitest/coverage-istanbul@npm:4.0.18" @@ -3856,6 +3915,22 @@ __metadata: languageName: node linkType: hard +"append-transform@npm:^2.0.0": + version: 2.0.0 + resolution: "append-transform@npm:2.0.0" + dependencies: + default-require-extensions: "npm:^3.0.0" + checksum: 10c0/f1505e4f4597f4eb7b3df8da898e431fc25d6cdc6c78d01c700a4fab38d835e7cbac693eade8df7b0a0944dc52a35f92b1771e440af59f1b1f8a1dadaba7d17b + languageName: node + linkType: hard + +"archy@npm:^1.0.0": + version: 1.0.0 + resolution: "archy@npm:1.0.0" + checksum: 10c0/200c849dd1c304ea9914827b0555e7e1e90982302d574153e28637db1a663c53de62bad96df42d50e8ce7fc18d05e3437d9aa8c4b383803763755f0956c7d308 + languageName: node + linkType: hard + "arg@npm:^4.1.0": version: 4.1.3 resolution: "arg@npm:4.1.3" @@ -3863,6 +3938,15 @@ __metadata: languageName: node linkType: hard +"argparse@npm:^1.0.7": + version: 1.0.10 + resolution: "argparse@npm:1.0.10" + dependencies: + sprintf-js: "npm:~1.0.2" + checksum: 10c0/b2972c5c23c63df66bca144dbc65d180efa74f25f8fd9b7d9a0a6c88ae839db32df3d54770dcb6460cf840d232b60695d1a6b1053f599d84e73f7437087712de + languageName: node + linkType: hard + "argparse@npm:^2.0.1": version: 2.0.1 resolution: "argparse@npm:2.0.1" @@ -4177,6 +4261,13 @@ __metadata: languageName: node linkType: hard +"base64-js@npm:^1.3.1": + version: 1.5.1 + resolution: "base64-js@npm:1.5.1" + checksum: 10c0/f23823513b63173a001030fae4f2dabe283b99a9d324ade3ad3d148e218134676f1ee8568c877cd79ec1c53158dcf2d2ba527a97c606618928ba99dd930102bf + languageName: node + linkType: hard + "bidi-js@npm:^1.0.3": version: 1.0.3 resolution: "bidi-js@npm:1.0.3" @@ -4193,6 +4284,17 @@ __metadata: languageName: node linkType: hard +"bl@npm:^4.0.3": + version: 4.1.0 + resolution: "bl@npm:4.1.0" + dependencies: + buffer: "npm:^5.5.0" + inherits: "npm:^2.0.4" + readable-stream: "npm:^3.4.0" + checksum: 10c0/02847e1d2cb089c9dc6958add42e3cdeaf07d13f575973963335ac0fdece563a50ac770ac4c8fa06492d2dd276f6cc3b7f08c7cd9c7a7ad0f8d388b2a28def5f + languageName: node + linkType: hard + "boolbase@npm:^1.0.0": version: 1.0.0 resolution: "boolbase@npm:1.0.0" @@ -4263,6 +4365,16 @@ __metadata: languageName: node linkType: hard +"buffer@npm:^5.5.0": + version: 5.7.1 + resolution: "buffer@npm:5.7.1" + dependencies: + base64-js: "npm:^1.3.1" + ieee754: "npm:^1.1.13" + checksum: 10c0/27cac81cff434ed2876058d72e7c4789d11ff1120ef32c9de48f59eab58179b66710c488987d295ae89a228f835fc66d088652dffeb8e3ba8659f80eb091d55e + languageName: node + linkType: hard + "bundle-name@npm:^4.1.0": version: 4.1.0 resolution: "bundle-name@npm:4.1.0" @@ -4292,6 +4404,18 @@ __metadata: languageName: node linkType: hard +"caching-transform@npm:^4.0.0": + version: 4.0.0 + resolution: "caching-transform@npm:4.0.0" + dependencies: + hasha: "npm:^5.0.0" + make-dir: "npm:^3.0.0" + package-hash: "npm:^4.0.0" + write-file-atomic: "npm:^3.0.0" + checksum: 10c0/7b33669dadfad292636578087a1aa7bcf9fbd60d6cbc67e8f288e3667397193c00bdac35bb84d34bd44fa9209405791fd3ab101c2126109e6eaaef1b899da759 + languageName: node + linkType: hard + "call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": version: 1.0.2 resolution: "call-bind-apply-helpers@npm:1.0.2" @@ -4355,7 +4479,7 @@ __metadata: languageName: node linkType: hard -"camelcase@npm:^5.3.1": +"camelcase@npm:^5.0.0, camelcase@npm:^5.3.1": version: 5.3.1 resolution: "camelcase@npm:5.3.1" checksum: 10c0/92ff9b443bfe8abb15f2b1513ca182d16126359ad4f955ebc83dc4ddcc4ef3fdd2c078bc223f2673dc223488e75c99b16cc4d056624374b799e6a1555cf61b23 @@ -4383,6 +4507,17 @@ __metadata: languageName: node linkType: hard +"canvas@npm:^3.2.1": + version: 3.2.1 + resolution: "canvas@npm:3.2.1" + dependencies: + node-addon-api: "npm:^7.0.0" + node-gyp: "npm:latest" + prebuild-install: "npm:^7.1.3" + checksum: 10c0/c0fd572a8b28e075b40a42b523bdf05e985feaeb18b56085432bfb91a3b905af48f89ec73ed4e795de892cb13f7332ceb0c78cf84c64281c41c29995665b89c8 + languageName: node + linkType: hard + "chai@npm:^5.2.0": version: 5.3.3 resolution: "chai@npm:5.3.3" @@ -4458,6 +4593,13 @@ __metadata: languageName: node linkType: hard +"chownr@npm:^1.1.1": + version: 1.1.4 + resolution: "chownr@npm:1.1.4" + checksum: 10c0/ed57952a84cc0c802af900cf7136de643d3aba2eecb59d29344bc2f3f9bf703a301b9d84cdc71f82c3ffc9ccde831b0d92f5b45f91727d6c9da62f23aef9d9db + languageName: node + linkType: hard + "chownr@npm:^2.0.0": version: 2.0.0 resolution: "chownr@npm:2.0.0" @@ -4491,6 +4633,17 @@ __metadata: languageName: node linkType: hard +"cliui@npm:^6.0.0": + version: 6.0.0 + resolution: "cliui@npm:6.0.0" + dependencies: + string-width: "npm:^4.2.0" + strip-ansi: "npm:^6.0.0" + wrap-ansi: "npm:^6.2.0" + checksum: 10c0/35229b1bb48647e882104cac374c9a18e34bbf0bace0e2cf03000326b6ca3050d6b59545d91e17bfe3705f4a0e2988787aa5cde6331bf5cbbf0164732cef6492 + languageName: node + linkType: hard + "cliui@npm:^7.0.2": version: 7.0.4 resolution: "cliui@npm:7.0.4" @@ -4559,6 +4712,13 @@ __metadata: languageName: node linkType: hard +"commondir@npm:^1.0.1": + version: 1.0.1 + resolution: "commondir@npm:1.0.1" + checksum: 10c0/33a124960e471c25ee19280c9ce31ccc19574b566dc514fe4f4ca4c34fa8b0b57cf437671f5de380e11353ea9426213fca17687dd2ef03134fea2dbc53809fd6 + languageName: node + linkType: hard + "compare-func@npm:^2.0.0": version: 2.0.0 resolution: "compare-func@npm:2.0.0" @@ -4861,6 +5021,13 @@ __metadata: languageName: node linkType: hard +"convert-source-map@npm:^1.7.0": + version: 1.9.0 + resolution: "convert-source-map@npm:1.9.0" + checksum: 10c0/281da55454bf8126cbc6625385928c43479f2060984180c42f3a86c8b8c12720a24eac260624a7d1e090004028d2dee78602330578ceec1a08e27cb8bb0a8a5b + languageName: node + linkType: hard + "convert-source-map@npm:^2.0.0": version: 2.0.0 resolution: "convert-source-map@npm:2.0.0" @@ -4949,7 +5116,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.6": +"cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" dependencies: @@ -5186,7 +5353,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:^4.4.0, debug@npm:^4.4.3": +"debug@npm:^4.1.1, debug@npm:^4.4.0, debug@npm:^4.4.3": version: 4.4.3 resolution: "debug@npm:4.4.3" dependencies: @@ -5208,7 +5375,7 @@ __metadata: languageName: node linkType: hard -"decamelize@npm:^1.1.0": +"decamelize@npm:^1.1.0, decamelize@npm:^1.2.0": version: 1.2.0 resolution: "decamelize@npm:1.2.0" checksum: 10c0/85c39fe8fbf0482d4a1e224ef0119db5c1897f8503bcef8b826adff7a1b11414972f6fef2d7dec2ee0b4be3863cf64ac1439137ae9e6af23a3d8dcbe26a5b4b2 @@ -5222,6 +5389,15 @@ __metadata: languageName: node linkType: hard +"decompress-response@npm:^6.0.0": + version: 6.0.0 + resolution: "decompress-response@npm:6.0.0" + dependencies: + mimic-response: "npm:^3.1.0" + checksum: 10c0/bd89d23141b96d80577e70c54fb226b2f40e74a6817652b80a116d7befb8758261ad073a8895648a29cc0a5947021ab66705cb542fa9c143c82022b27c5b175e + languageName: node + linkType: hard + "deep-eql@npm:^5.0.1": version: 5.0.2 resolution: "deep-eql@npm:5.0.2" @@ -5255,6 +5431,13 @@ __metadata: languageName: node linkType: hard +"deep-extend@npm:^0.6.0": + version: 0.6.0 + resolution: "deep-extend@npm:0.6.0" + checksum: 10c0/1c6b0abcdb901e13a44c7d699116d3d4279fdb261983122a3783e7273844d5f2537dc2e1c454a23fcf645917f93fbf8d07101c1d03c015a87faa662755212566 + languageName: node + linkType: hard + "deep-is@npm:^0.1.3": version: 0.1.4 resolution: "deep-is@npm:0.1.4" @@ -5279,6 +5462,15 @@ __metadata: languageName: node linkType: hard +"default-require-extensions@npm:^3.0.0": + version: 3.0.1 + resolution: "default-require-extensions@npm:3.0.1" + dependencies: + strip-bom: "npm:^4.0.0" + checksum: 10c0/5ca376cb527d9474336ad76dd302d06367a7163379dda26558258de26f85861e696d0b7bb19ee3c6b8456bb7c95cdc0e4e4d45c2aa487e61b2d3b60d80c10648 + languageName: node + linkType: hard + "define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4": version: 1.1.4 resolution: "define-data-property@npm:1.1.4" @@ -5322,7 +5514,7 @@ __metadata: languageName: node linkType: hard -"detect-libc@npm:^2.0.3": +"detect-libc@npm:^2.0.0, detect-libc@npm:^2.0.3": version: 2.1.2 resolution: "detect-libc@npm:2.1.2" checksum: 10c0/acc675c29a5649fa1fb6e255f993b8ee829e510b6b56b0910666949c80c364738833417d0edb5f90e4e46be17228b0f2b66a010513984e18b15deeeac49369c4 @@ -5545,6 +5737,15 @@ __metadata: languageName: node linkType: hard +"end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1": + version: 1.4.5 + resolution: "end-of-stream@npm:1.4.5" + dependencies: + once: "npm:^1.4.0" + checksum: 10c0/b0701c92a10b89afb1cb45bf54a5292c6f008d744eb4382fa559d54775ff31617d1d7bc3ef617575f552e24fad2c7c1a1835948c66b3f3a4be0a6c1f35c883d8 + languageName: node + linkType: hard + "entities@npm:^4.2.0, entities@npm:^4.4.0, entities@npm:^4.5.0": version: 4.5.0 resolution: "entities@npm:4.5.0" @@ -5911,6 +6112,13 @@ __metadata: languageName: node linkType: hard +"es6-error@npm:^4.0.1": + version: 4.1.1 + resolution: "es6-error@npm:4.1.1" + checksum: 10c0/357663fb1e845c047d548c3d30f86e005db71e122678f4184ced0693f634688c3f3ef2d7de7d4af732f734de01f528b05954e270f06aa7d133679fb9fe6600ef + languageName: node + linkType: hard + "esbuild@npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0, esbuild@npm:^0.27.0": version: 0.27.3 resolution: "esbuild@npm:0.27.3" @@ -6296,7 +6504,7 @@ __metadata: languageName: node linkType: hard -"esprima@npm:~4.0.0": +"esprima@npm:^4.0.0, esprima@npm:~4.0.0": version: 4.0.1 resolution: "esprima@npm:4.0.1" bin: @@ -6363,6 +6571,13 @@ __metadata: languageName: node linkType: hard +"expand-template@npm:^2.0.3": + version: 2.0.3 + resolution: "expand-template@npm:2.0.3" + checksum: 10c0/1c9e7afe9acadf9d373301d27f6a47b34e89b3391b1ef38b7471d381812537ef2457e620ae7f819d2642ce9c43b189b3583813ec395e2938319abe356a9b2f51 + languageName: node + linkType: hard + "expect-type@npm:^1.2.2": version: 1.3.0 resolution: "expect-type@npm:1.3.0" @@ -6449,6 +6664,17 @@ __metadata: languageName: node linkType: hard +"find-cache-dir@npm:^3.2.0": + version: 3.3.2 + resolution: "find-cache-dir@npm:3.3.2" + dependencies: + commondir: "npm:^1.0.1" + make-dir: "npm:^3.0.2" + pkg-dir: "npm:^4.1.0" + checksum: 10c0/92747cda42bff47a0266b06014610981cfbb71f55d60f2c8216bc3108c83d9745507fb0b14ecf6ab71112bed29cd6fb1a137ee7436179ea36e11287e3159e587 + languageName: node + linkType: hard + "find-up@npm:^2.0.0": version: 2.1.0 resolution: "find-up@npm:2.1.0" @@ -6467,7 +6693,7 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^4.1.0": +"find-up@npm:^4.0.0, find-up@npm:^4.1.0": version: 4.1.0 resolution: "find-up@npm:4.1.0" dependencies: @@ -6536,6 +6762,16 @@ __metadata: languageName: node linkType: hard +"foreground-child@npm:^2.0.0": + version: 2.0.0 + resolution: "foreground-child@npm:2.0.0" + dependencies: + cross-spawn: "npm:^7.0.0" + signal-exit: "npm:^3.0.2" + checksum: 10c0/6719982783a448162f9a01500757fb2053bc5dcd4d67c7cd30739b38ccc01b39f84e408c30989d1d8774519c021c0498e2450ab127690fb09d7f2568fd94ffcc + languageName: node + linkType: hard + "foreground-child@npm:^3.1.0": version: 3.1.1 resolution: "foreground-child@npm:3.1.1" @@ -6546,6 +6782,30 @@ __metadata: languageName: node linkType: hard +"foreground-child@npm:^3.3.0": + version: 3.3.1 + resolution: "foreground-child@npm:3.3.1" + dependencies: + cross-spawn: "npm:^7.0.6" + signal-exit: "npm:^4.0.1" + checksum: 10c0/8986e4af2430896e65bc2788d6679067294d6aee9545daefc84923a0a4b399ad9c7a3ea7bd8c0b2b80fdf4a92de4c69df3f628233ff3224260e9c1541a9e9ed3 + languageName: node + linkType: hard + +"fromentries@npm:^1.2.0": + version: 1.3.2 + resolution: "fromentries@npm:1.3.2" + checksum: 10c0/63938819a86e39f490b0caa1f6b38b8ad04f41ccd2a1c144eb48a21f76e4dbc074bc62e97abb053c7c1f541ecc70cf0b8aaa98eed3fe02206db9b6f9bb9a6a47 + languageName: node + linkType: hard + +"fs-constants@npm:^1.0.0": + version: 1.0.0 + resolution: "fs-constants@npm:1.0.0" + checksum: 10c0/a0cde99085f0872f4d244e83e03a46aa387b74f5a5af750896c6b05e9077fac00e9932fdf5aef84f2f16634cd473c63037d7a512576da7d5c2b9163d1909f3a8 + languageName: node + linkType: hard + "fs-minipass@npm:^2.0.0": version: 2.1.0 resolution: "fs-minipass@npm:2.1.0" @@ -6564,6 +6824,23 @@ __metadata: languageName: node linkType: hard +"fs.realpath@npm:^1.0.0": + version: 1.0.0 + resolution: "fs.realpath@npm:1.0.0" + checksum: 10c0/444cf1291d997165dfd4c0d58b69f0e4782bfd9149fd72faa4fe299e68e0e93d6db941660b37dd29153bf7186672ececa3b50b7e7249477b03fdf850f287c948 + languageName: node + linkType: hard + +"fsevents@npm:2.3.2": + version: 2.3.2 + resolution: "fsevents@npm:2.3.2" + dependencies: + node-gyp: "npm:latest" + checksum: 10c0/be78a3efa3e181cda3cf7a4637cb527bcebb0bd0ea0440105a3bb45b86f9245b307dc10a2507e8f4498a7d4ec349d1910f4d73e4d4495b16103106e07eee735b + conditions: os=darwin + languageName: node + linkType: hard + "fsevents@npm:~2.3.2, fsevents@npm:~2.3.3": version: 2.3.3 resolution: "fsevents@npm:2.3.3" @@ -6574,6 +6851,15 @@ __metadata: languageName: node linkType: hard +"fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin": + version: 2.3.2 + resolution: "fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin::version=2.3.2&hash=df0bf1" + dependencies: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + "fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin": version: 2.3.3 resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" @@ -6637,7 +6923,7 @@ __metadata: languageName: node linkType: hard -"get-caller-file@npm:^2.0.5": +"get-caller-file@npm:^2.0.1, get-caller-file@npm:^2.0.5": version: 2.0.5 resolution: "get-caller-file@npm:2.0.5" checksum: 10c0/c6c7b60271931fa752aeb92f2b47e355eac1af3a2673f47c9589e8f8a41adc74d45551c1bc57b5e66a80609f10ffb72b6f575e4370d61cc3f7f3aaff01757cde @@ -6685,6 +6971,13 @@ __metadata: languageName: node linkType: hard +"get-package-type@npm:^0.1.0": + version: 0.1.0 + resolution: "get-package-type@npm:0.1.0" + checksum: 10c0/e34cdf447fdf1902a1f6d5af737eaadf606d2ee3518287abde8910e04159368c268568174b2e71102b87b26c2020486f126bfca9c4fb1ceb986ff99b52ecd1be + languageName: node + linkType: hard + "get-pkg-repo@npm:^4.0.0": version: 4.2.1 resolution: "get-pkg-repo@npm:4.2.1" @@ -6790,6 +7083,13 @@ __metadata: languageName: node linkType: hard +"github-from-package@npm:0.0.0": + version: 0.0.0 + resolution: "github-from-package@npm:0.0.0" + checksum: 10c0/737ee3f52d0a27e26332cde85b533c21fcdc0b09fb716c3f8e522cfaa9c600d4a631dec9fcde179ec9d47cca89017b7848ed4d6ae6b6b78f936c06825b1fcc12 + languageName: node + linkType: hard + "glob-parent@npm:^6.0.2": version: 6.0.2 resolution: "glob-parent@npm:6.0.2" @@ -6841,6 +7141,20 @@ __metadata: languageName: node linkType: hard +"glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6": + version: 7.2.3 + resolution: "glob@npm:7.2.3" + dependencies: + fs.realpath: "npm:^1.0.0" + inflight: "npm:^1.0.4" + inherits: "npm:2" + minimatch: "npm:^3.1.1" + once: "npm:^1.3.0" + path-is-absolute: "npm:^1.0.0" + checksum: 10c0/65676153e2b0c9095100fe7f25a778bf45608eeb32c6048cf307f579649bcc30353277b3b898a3792602c65764e5baa4f643714dfbdfd64ea271d210c7a425fe + languageName: node + linkType: hard + "global-directory@npm:^4.0.1": version: 4.0.1 resolution: "global-directory@npm:4.0.1" @@ -6906,7 +7220,7 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.6": +"graceful-fs@npm:^4.1.15, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 @@ -7014,6 +7328,16 @@ __metadata: languageName: node linkType: hard +"hasha@npm:^5.0.0": + version: 5.2.2 + resolution: "hasha@npm:5.2.2" + dependencies: + is-stream: "npm:^2.0.0" + type-fest: "npm:^0.8.0" + checksum: 10c0/9d10d4e665a37beea6e18ba3a0c0399a05b26e505c5ff2fe9115b64fedb3ca95f68c89cf15b08ee4d09fd3064b5e1bfc8e8247353c7aa6b7388471d0f86dca74 + languageName: node + linkType: hard + "hasown@npm:^2.0.0, hasown@npm:^2.0.1, hasown@npm:^2.0.2": version: 2.0.2 resolution: "hasown@npm:2.0.2" @@ -7126,6 +7450,13 @@ __metadata: languageName: node linkType: hard +"ieee754@npm:^1.1.13": + version: 1.2.1 + resolution: "ieee754@npm:1.2.1" + checksum: 10c0/b0782ef5e0935b9f12883a2e2aa37baa75da6e66ce6515c168697b42160807d9330de9a32ec1ed73149aea02e0d822e572bca6f1e22bdcbd2149e13b050b17bb + languageName: node + linkType: hard + "ignore@npm:^5.2.0": version: 5.3.1 resolution: "ignore@npm:5.3.1" @@ -7178,7 +7509,17 @@ __metadata: languageName: node linkType: hard -"inherits@npm:^2.0.3, inherits@npm:~2.0.3": +"inflight@npm:^1.0.4": + version: 1.0.6 + resolution: "inflight@npm:1.0.6" + dependencies: + once: "npm:^1.3.0" + wrappy: "npm:1" + checksum: 10c0/7faca22584600a9dc5b9fca2cd5feb7135ac8c935449837b315676b4c90aa4f391ec4f42240178244b5a34e8bede1948627fda392ca3191522fc46b34e985ab2 + languageName: node + linkType: hard + +"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 @@ -7192,7 +7533,7 @@ __metadata: languageName: node linkType: hard -"ini@npm:^1.3.2, ini@npm:^1.3.4": +"ini@npm:^1.3.2, ini@npm:^1.3.4, ini@npm:~1.3.0": version: 1.3.8 resolution: "ini@npm:1.3.8" checksum: 10c0/ec93838d2328b619532e4f1ff05df7909760b6f66d9c9e2ded11e5c1897d6f2f9980c54dd638f88654b00919ce31e827040631eab0a3969e4d1abefa0719516a @@ -7573,6 +7914,13 @@ __metadata: languageName: node linkType: hard +"is-stream@npm:^2.0.0": + version: 2.0.1 + resolution: "is-stream@npm:2.0.1" + checksum: 10c0/7c284241313fc6efc329b8d7f08e16c0efeb6baab1b4cd0ba579eb78e5af1aa5da11e68559896a2067cd6c526bd29241dda4eb1225e627d5aa1a89a76d4635a5 + languageName: node + linkType: hard + "is-string@npm:^1.0.5, is-string@npm:^1.0.7": version: 1.0.7 resolution: "is-string@npm:1.0.7" @@ -7639,6 +7987,13 @@ __metadata: languageName: node linkType: hard +"is-typedarray@npm:^1.0.0": + version: 1.0.0 + resolution: "is-typedarray@npm:1.0.0" + checksum: 10c0/4c096275ba041a17a13cca33ac21c16bc4fd2d7d7eb94525e7cd2c2f2c1a3ab956e37622290642501ff4310601e413b675cf399ad6db49855527d2163b3eeeec + languageName: node + linkType: hard + "is-weakmap@npm:^2.0.2": version: 2.0.2 resolution: "is-weakmap@npm:2.0.2" @@ -7681,6 +8036,13 @@ __metadata: languageName: node linkType: hard +"is-windows@npm:^1.0.2": + version: 1.0.2 + resolution: "is-windows@npm:1.0.2" + checksum: 10c0/b32f418ab3385604a66f1b7a3ce39d25e8881dee0bd30816dc8344ef6ff9df473a732bcc1ec4e84fe99b2f229ae474f7133e8e93f9241686cfcf7eebe53ba7a5 + languageName: node + linkType: hard + "is-wsl@npm:^3.1.0": version: 3.1.1 resolution: "is-wsl@npm:3.1.1" @@ -7725,7 +8087,16 @@ __metadata: languageName: node linkType: hard -"istanbul-lib-instrument@npm:^6.0.3": +"istanbul-lib-hook@npm:^3.0.0": + version: 3.0.0 + resolution: "istanbul-lib-hook@npm:3.0.0" + dependencies: + append-transform: "npm:^2.0.0" + checksum: 10c0/0029bdbc4ae82c2a5a0b48a2f4ba074de72601a5d27505493c9be83d4c7952039ad787d2f6d1321710b75a05059c4335a0eb7c8857ca82e7e6d19f8d88d03b46 + languageName: node + linkType: hard + +"istanbul-lib-instrument@npm:^6.0.2, istanbul-lib-instrument@npm:^6.0.3": version: 6.0.3 resolution: "istanbul-lib-instrument@npm:6.0.3" dependencies: @@ -7738,6 +8109,20 @@ __metadata: languageName: node linkType: hard +"istanbul-lib-processinfo@npm:^2.0.2": + version: 2.0.3 + resolution: "istanbul-lib-processinfo@npm:2.0.3" + dependencies: + archy: "npm:^1.0.0" + cross-spawn: "npm:^7.0.3" + istanbul-lib-coverage: "npm:^3.2.0" + p-map: "npm:^3.0.0" + rimraf: "npm:^3.0.0" + uuid: "npm:^8.3.2" + checksum: 10c0/ffd0f9b1c8e266e980580f83e65397caeace3958e4b4326b4479dcb0e41a450698387b96b4d4823e63b7c4a403f72e6e30d9e788ddcf153edb422a9d6f64a998 + languageName: node + linkType: hard + "istanbul-lib-report@npm:^3.0.0, istanbul-lib-report@npm:^3.0.1": version: 3.0.1 resolution: "istanbul-lib-report@npm:3.0.1" @@ -7749,7 +8134,18 @@ __metadata: languageName: node linkType: hard -"istanbul-reports@npm:^3.2.0": +"istanbul-lib-source-maps@npm:^4.0.0": + version: 4.0.1 + resolution: "istanbul-lib-source-maps@npm:4.0.1" + dependencies: + debug: "npm:^4.1.1" + istanbul-lib-coverage: "npm:^3.0.0" + source-map: "npm:^0.6.1" + checksum: 10c0/19e4cc405016f2c906dff271a76715b3e881fa9faeb3f09a86cb99b8512b3a5ed19cadfe0b54c17ca0e54c1142c9c6de9330d65506e35873994e06634eebeb66 + languageName: node + linkType: hard + +"istanbul-reports@npm:^3.0.2, istanbul-reports@npm:^3.2.0": version: 3.2.0 resolution: "istanbul-reports@npm:3.2.0" dependencies: @@ -7846,6 +8242,18 @@ __metadata: languageName: node linkType: hard +"js-yaml@npm:^3.13.1": + version: 3.14.2 + resolution: "js-yaml@npm:3.14.2" + dependencies: + argparse: "npm:^1.0.7" + esprima: "npm:^4.0.0" + bin: + js-yaml: bin/js-yaml.js + checksum: 10c0/3261f25912f5dd76605e5993d0a126c2b6c346311885d3c483706cd722efe34f697ea0331f654ce27c00a42b426e524518ec89d65ed02ea47df8ad26dcc8ce69 + languageName: node + linkType: hard + "js-yaml@npm:^4.1.0": version: 4.1.0 resolution: "js-yaml@npm:4.1.0" @@ -8153,6 +8561,13 @@ __metadata: languageName: node linkType: hard +"lodash.flattendeep@npm:^4.4.0": + version: 4.4.0 + resolution: "lodash.flattendeep@npm:4.4.0" + checksum: 10c0/83cb80754b921fb4ed2c222b91a82b2524f3bdc60c3ae91e00688bd4bf1bcc28b8a2cc250e11fdc1b6da3a2de09e57008e13f15a209cafdd4f9163d047f97544 + languageName: node + linkType: hard + "lodash.isequal@npm:^4.5.0": version: 4.5.0 resolution: "lodash.isequal@npm:4.5.0" @@ -8354,6 +8769,15 @@ __metadata: languageName: node linkType: hard +"make-dir@npm:^3.0.0, make-dir@npm:^3.0.2": + version: 3.1.0 + resolution: "make-dir@npm:3.1.0" + dependencies: + semver: "npm:^6.0.0" + checksum: 10c0/56aaafefc49c2dfef02c5c95f9b196c4eb6988040cf2c712185c7fe5c99b4091591a7fc4d4eafaaefa70ff763a26f6ab8c3ff60b9e75ea19876f49b18667ecaa + languageName: node + linkType: hard + "make-dir@npm:^4.0.0": version: 4.0.0 resolution: "make-dir@npm:4.0.0" @@ -8464,6 +8888,13 @@ __metadata: languageName: node linkType: hard +"mimic-response@npm:^3.1.0": + version: 3.1.0 + resolution: "mimic-response@npm:3.1.0" + checksum: 10c0/0d6f07ce6e03e9e4445bee655202153bdb8a98d67ee8dc965ac140900d7a2688343e6b4c9a72cfc9ef2f7944dfd76eef4ab2482eb7b293a68b84916bac735362 + languageName: node + linkType: hard + "min-indent@npm:^1.0.0, min-indent@npm:^1.0.1": version: 1.0.1 resolution: "min-indent@npm:1.0.1" @@ -8498,6 +8929,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^3.1.1": + version: 3.1.3 + resolution: "minimatch@npm:3.1.3" + dependencies: + brace-expansion: "npm:^1.1.7" + checksum: 10c0/c1ffce4be47e88df013f66f55176c25a93fdd8ad15735309cf1782f0433a02f363cee298f8763ceaaaf85e70ff7f30dc84a1a8d00a6fb6ca72032e5b51f9b89c + languageName: node + linkType: hard + "minimatch@npm:^9.0.1": version: 9.0.3 resolution: "minimatch@npm:9.0.3" @@ -8527,7 +8967,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.2.0, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.8": +"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.8": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6 @@ -8639,6 +9079,13 @@ __metadata: languageName: node linkType: hard +"mkdirp-classic@npm:^0.5.2, mkdirp-classic@npm:^0.5.3": + version: 0.5.3 + resolution: "mkdirp-classic@npm:0.5.3" + checksum: 10c0/95371d831d196960ddc3833cc6907e6b8f67ac5501a6582f47dfae5eb0f092e9f8ce88e0d83afcae95d6e2b61a01741ba03714eeafb6f7a6e9dcc158ac85b168 + languageName: node + linkType: hard + "mkdirp@npm:^1.0.3": version: 1.0.4 resolution: "mkdirp@npm:1.0.4" @@ -8713,6 +9160,13 @@ __metadata: languageName: node linkType: hard +"napi-build-utils@npm:^2.0.0": + version: 2.0.0 + resolution: "napi-build-utils@npm:2.0.0" + checksum: 10c0/5833aaeb5cc5c173da47a102efa4680a95842c13e0d9cc70428bd3ee8d96bb2172f8860d2811799b5daa5cbeda779933601492a2028a6a5351c6d0fcf6de83db + languageName: node + linkType: hard + "natural-compare@npm:^1.4.0": version: 1.4.0 resolution: "natural-compare@npm:1.4.0" @@ -8744,6 +9198,15 @@ __metadata: languageName: node linkType: hard +"node-abi@npm:^3.3.0": + version: 3.87.0 + resolution: "node-abi@npm:3.87.0" + dependencies: + semver: "npm:^7.3.5" + checksum: 10c0/41cfc361edd1b0711d412ca9e1a475180c5b897868bd5583df7ff73e30e6044cc7de307df36c2257203320f17fadf7e82dfdf5a9f6fd510a8578e3fe3ed67ebb + languageName: node + linkType: hard + "node-addon-api@npm:^7.0.0": version: 7.1.1 resolution: "node-addon-api@npm:7.1.1" @@ -8773,6 +9236,15 @@ __metadata: languageName: node linkType: hard +"node-preload@npm:^0.2.1": + version: 0.2.1 + resolution: "node-preload@npm:0.2.1" + dependencies: + process-on-spawn: "npm:^1.0.0" + checksum: 10c0/7ae3def896626701e2a27b0c8119e0234089db4317b8c16bb8c44bee9abb82c0e38d57e6317d480970f5a2510e44185af81d3ea85be1a78311701f66f912e9e4 + languageName: node + linkType: hard + "node-releases@npm:^2.0.14": version: 2.0.14 resolution: "node-releases@npm:2.0.14" @@ -8842,6 +9314,43 @@ __metadata: languageName: node linkType: hard +"nyc@npm:^17.1.0": + version: 17.1.0 + resolution: "nyc@npm:17.1.0" + dependencies: + "@istanbuljs/load-nyc-config": "npm:^1.0.0" + "@istanbuljs/schema": "npm:^0.1.2" + caching-transform: "npm:^4.0.0" + convert-source-map: "npm:^1.7.0" + decamelize: "npm:^1.2.0" + find-cache-dir: "npm:^3.2.0" + find-up: "npm:^4.1.0" + foreground-child: "npm:^3.3.0" + get-package-type: "npm:^0.1.0" + glob: "npm:^7.1.6" + istanbul-lib-coverage: "npm:^3.0.0" + istanbul-lib-hook: "npm:^3.0.0" + istanbul-lib-instrument: "npm:^6.0.2" + istanbul-lib-processinfo: "npm:^2.0.2" + istanbul-lib-report: "npm:^3.0.0" + istanbul-lib-source-maps: "npm:^4.0.0" + istanbul-reports: "npm:^3.0.2" + make-dir: "npm:^3.0.0" + node-preload: "npm:^0.2.1" + p-map: "npm:^3.0.0" + process-on-spawn: "npm:^1.0.0" + resolve-from: "npm:^5.0.0" + rimraf: "npm:^3.0.0" + signal-exit: "npm:^3.0.2" + spawn-wrap: "npm:^2.0.0" + test-exclude: "npm:^6.0.0" + yargs: "npm:^15.0.2" + bin: + nyc: bin/nyc.js + checksum: 10c0/653497bf11c53c70d821c18a2bfb7dba310b297b8bc83e5392e560c3d60d4dc9836b6c44f060065dfa99f7dacfd49147f8f60b160dfbe3f722517d4e7e236db2 + languageName: node + linkType: hard + "object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" @@ -8971,6 +9480,15 @@ __metadata: languageName: node linkType: hard +"once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0": + version: 1.4.0 + resolution: "once@npm:1.4.0" + dependencies: + wrappy: "npm:1" + checksum: 10c0/5d48aca287dfefabd756621c5dfce5c91a549a93e9fdb7b8246bc4c4790aa2ec17b34a260530474635147aeb631a2dcc8b32c613df0675f96041cbb8244517d0 + languageName: node + linkType: hard + "open@npm:^10.2.0": version: 10.2.0 resolution: "open@npm:10.2.0" @@ -9071,6 +9589,15 @@ __metadata: languageName: node linkType: hard +"p-map@npm:^3.0.0": + version: 3.0.0 + resolution: "p-map@npm:3.0.0" + dependencies: + aggregate-error: "npm:^3.0.0" + checksum: 10c0/297930737e52412ad9f5787c52774ad6496fad9a8be5f047e75fd0a3dc61930d8f7a9b2bbe1c4d1404e54324228a4f69721da2538208dadaa4ef4c81773c9f20 + languageName: node + linkType: hard + "p-map@npm:^4.0.0": version: 4.0.0 resolution: "p-map@npm:4.0.0" @@ -9094,6 +9621,18 @@ __metadata: languageName: node linkType: hard +"package-hash@npm:^4.0.0": + version: 4.0.0 + resolution: "package-hash@npm:4.0.0" + dependencies: + graceful-fs: "npm:^4.1.15" + hasha: "npm:^5.0.0" + lodash.flattendeep: "npm:^4.4.0" + release-zalgo: "npm:^1.0.0" + checksum: 10c0/2108b685fd5b2a32323aeed5caf2afef8c5fcf680527b09c7e2eaa05cf04b09a7c586860319097fc589ad028a3d94b2da68e8ab1935249aa95e8162ffd622729 + languageName: node + linkType: hard + "package-json-from-dist@npm:^1.0.0": version: 1.0.1 resolution: "package-json-from-dist@npm:1.0.1" @@ -9162,6 +9701,13 @@ __metadata: languageName: node linkType: hard +"path-is-absolute@npm:^1.0.0": + version: 1.0.1 + resolution: "path-is-absolute@npm:1.0.1" + checksum: 10c0/127da03c82172a2a50099cddbf02510c1791fc2cc5f7713ddb613a56838db1e8168b121a920079d052e0936c23005562059756d653b7c544c53185efe53be078 + languageName: node + linkType: hard + "path-key@npm:^3.1.0": version: 3.1.1 resolution: "path-key@npm:3.1.1" @@ -9292,6 +9838,26 @@ __metadata: languageName: node linkType: hard +"pixelmatch@npm:7.1.0": + version: 7.1.0 + resolution: "pixelmatch@npm:7.1.0" + dependencies: + pngjs: "npm:^7.0.0" + bin: + pixelmatch: bin/pixelmatch + checksum: 10c0/ff069f92edaa841ac9b58b0ab74e1afa1f3b5e770eea0218c96bac1da4e752f5f6b79a0f9c4ba6b02afb955d39b8c78bcc3cc884f8122b67a1f2efbbccbe1a73 + languageName: node + linkType: hard + +"pkg-dir@npm:^4.1.0": + version: 4.2.0 + resolution: "pkg-dir@npm:4.2.0" + dependencies: + find-up: "npm:^4.0.0" + checksum: 10c0/c56bda7769e04907a88423feb320babaed0711af8c436ce3e56763ab1021ba107c7b0cafb11cde7529f669cfc22bffcaebffb573645cbd63842ea9fb17cd7728 + languageName: node + linkType: hard + "pkg-types@npm:^1.3.1": version: 1.3.1 resolution: "pkg-types@npm:1.3.1" @@ -9314,6 +9880,37 @@ __metadata: languageName: node linkType: hard +"playwright-core@npm:1.58.2": + version: 1.58.2 + resolution: "playwright-core@npm:1.58.2" + bin: + playwright-core: cli.js + checksum: 10c0/5aa15b2b764e6ffe738293a09081a6f7023847a0dbf4cd05fe10eed2e25450d321baf7482f938f2d2eb330291e197fa23e57b29a5b552b89927ceb791266225b + languageName: node + linkType: hard + +"playwright@npm:^1.55.0": + version: 1.58.2 + resolution: "playwright@npm:1.58.2" + dependencies: + fsevents: "npm:2.3.2" + playwright-core: "npm:1.58.2" + dependenciesMeta: + fsevents: + optional: true + bin: + playwright: cli.js + checksum: 10c0/d060d9b7cc124bd8b5dffebaab5e84f6b34654a553758fe7b19cc598dfbee93f6ecfbdc1832b40a6380ae04eade86ef3285ba03aa0b136799e83402246dc0727 + languageName: node + linkType: hard + +"pngjs@npm:^7.0.0": + version: 7.0.0 + resolution: "pngjs@npm:7.0.0" + checksum: 10c0/0d4c7a0fd476a9c33df7d0a2a73e1d56537628a668841f6995c2bca070cf30819f9254a64363266bc14ef2fee47659dd3b4f2b18eec7ab65143015139f497b38 + languageName: node + linkType: hard + "possible-typed-array-names@npm:^1.0.0": version: 1.0.0 resolution: "possible-typed-array-names@npm:1.0.0" @@ -9353,6 +9950,28 @@ __metadata: languageName: node linkType: hard +"prebuild-install@npm:^7.1.3": + version: 7.1.3 + resolution: "prebuild-install@npm:7.1.3" + dependencies: + detect-libc: "npm:^2.0.0" + expand-template: "npm:^2.0.3" + github-from-package: "npm:0.0.0" + minimist: "npm:^1.2.3" + mkdirp-classic: "npm:^0.5.3" + napi-build-utils: "npm:^2.0.0" + node-abi: "npm:^3.3.0" + pump: "npm:^3.0.0" + rc: "npm:^1.2.7" + simple-get: "npm:^4.0.0" + tar-fs: "npm:^2.0.0" + tunnel-agent: "npm:^0.6.0" + bin: + prebuild-install: bin.js + checksum: 10c0/25919a42b52734606a4036ab492d37cfe8b601273d8dfb1fa3c84e141a0a475e7bad3ab848c741d2f810cef892fcf6059b8c7fe5b29f98d30e0c29ad009bedff + languageName: node + linkType: hard + "prelude-ls@npm:^1.2.1": version: 1.2.1 resolution: "prelude-ls@npm:1.2.1" @@ -9385,6 +10004,15 @@ __metadata: languageName: node linkType: hard +"process-on-spawn@npm:^1.0.0": + version: 1.1.0 + resolution: "process-on-spawn@npm:1.1.0" + dependencies: + fromentries: "npm:^1.2.0" + checksum: 10c0/d7379a78e2ecc482d1f79be480505b68449b46c8736bcd94ae839c979f39517425b23d44d4170a8dc0ed5fe5f795e00fdff701c305d06d92dd899e132e3ee8b0 + languageName: node + linkType: hard + "promise-retry@npm:^2.0.1": version: 2.0.1 resolution: "promise-retry@npm:2.0.1" @@ -9549,6 +10177,16 @@ __metadata: languageName: node linkType: hard +"pump@npm:^3.0.0": + version: 3.0.3 + resolution: "pump@npm:3.0.3" + dependencies: + end-of-stream: "npm:^1.1.0" + once: "npm:^1.3.1" + checksum: 10c0/ada5cdf1d813065bbc99aa2c393b8f6beee73b5de2890a8754c9f488d7323ffd2ca5f5a0943b48934e3fcbd97637d0337369c3c631aeb9614915db629f1c75c9 + languageName: node + linkType: hard + "punycode@npm:^2.1.0, punycode@npm:^2.3.1": version: 2.3.1 resolution: "punycode@npm:2.3.1" @@ -9577,6 +10215,20 @@ __metadata: languageName: node linkType: hard +"rc@npm:^1.2.7": + version: 1.2.8 + resolution: "rc@npm:1.2.8" + dependencies: + deep-extend: "npm:^0.6.0" + ini: "npm:~1.3.0" + minimist: "npm:^1.2.0" + strip-json-comments: "npm:~2.0.1" + bin: + rc: ./cli.js + checksum: 10c0/24a07653150f0d9ac7168e52943cc3cb4b7a22c0e43c7dff3219977c2fdca5a2760a304a029c20811a0e79d351f57d46c9bde216193a0f73978496afc2b85b15 + languageName: node + linkType: hard + "react-docgen-typescript@npm:^2.2.2": version: 2.2.2 resolution: "react-docgen-typescript@npm:2.2.2" @@ -9754,7 +10406,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:3, readable-stream@npm:^3.0.0, readable-stream@npm:^3.0.2": +"readable-stream@npm:3, readable-stream@npm:^3.0.0, readable-stream@npm:^3.0.2, readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0": version: 3.6.2 resolution: "readable-stream@npm:3.6.2" dependencies: @@ -9891,6 +10543,15 @@ __metadata: languageName: node linkType: hard +"release-zalgo@npm:^1.0.0": + version: 1.0.0 + resolution: "release-zalgo@npm:1.0.0" + dependencies: + es6-error: "npm:^4.0.1" + checksum: 10c0/9e161feb073f9e3aa714bb077d67592c34ee578f5b9cff8e2d492423fe2002d5b1e6d11ffcd5c564b9a0ee9435f25569567b658a82b9af931e7ac1313925628a + languageName: node + linkType: hard + "request-light@npm:^0.7.0": version: 0.7.0 resolution: "request-light@npm:0.7.0" @@ -9912,6 +10573,13 @@ __metadata: languageName: node linkType: hard +"require-main-filename@npm:^2.0.0": + version: 2.0.0 + resolution: "require-main-filename@npm:2.0.0" + checksum: 10c0/db91467d9ead311b4111cbd73a4e67fa7820daed2989a32f7023785a2659008c6d119752d9c4ac011ae07e537eb86523adff99804c5fdb39cd3a017f9b401bb6 + languageName: node + linkType: hard + "resolve-from@npm:^4.0.0": version: 4.0.0 resolution: "resolve-from@npm:4.0.0" @@ -9992,6 +10660,17 @@ __metadata: languageName: node linkType: hard +"rimraf@npm:^3.0.0": + version: 3.0.2 + resolution: "rimraf@npm:3.0.2" + dependencies: + glob: "npm:^7.1.3" + bin: + rimraf: bin.js + checksum: 10c0/9cb7757acb489bd83757ba1a274ab545eafd75598a9d817e0c3f8b164238dd90eba50d6b848bd4dcc5f3040912e882dc7ba71653e35af660d77b25c381d402e8 + languageName: node + linkType: hard + "rollup@npm:^4.43.0": version: 4.58.0 resolution: "rollup@npm:4.58.0" @@ -10114,6 +10793,13 @@ __metadata: languageName: node linkType: hard +"safe-buffer@npm:^5.0.1, safe-buffer@npm:~5.2.0": + version: 5.2.1 + resolution: "safe-buffer@npm:5.2.1" + checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 + languageName: node + linkType: hard + "safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": version: 5.1.2 resolution: "safe-buffer@npm:5.1.2" @@ -10121,13 +10807,6 @@ __metadata: languageName: node linkType: hard -"safe-buffer@npm:~5.2.0": - version: 5.2.1 - resolution: "safe-buffer@npm:5.2.1" - checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 - languageName: node - linkType: hard - "safe-push-apply@npm:^1.0.0": version: 1.0.0 resolution: "safe-push-apply@npm:1.0.0" @@ -10272,6 +10951,13 @@ __metadata: languageName: node linkType: hard +"set-blocking@npm:^2.0.0": + version: 2.0.0 + resolution: "set-blocking@npm:2.0.0" + checksum: 10c0/9f8c1b2d800800d0b589de1477c753492de5c1548d4ade52f57f1d1f5e04af5481554d75ce5e5c43d4004b80a3eb714398d6907027dc0534177b7539119f4454 + languageName: node + linkType: hard + "set-function-length@npm:^1.2.1, set-function-length@npm:^1.2.2": version: 1.2.2 resolution: "set-function-length@npm:1.2.2" @@ -10392,6 +11078,13 @@ __metadata: languageName: node linkType: hard +"signal-exit@npm:^3.0.2": + version: 3.0.7 + resolution: "signal-exit@npm:3.0.7" + checksum: 10c0/25d272fa73e146048565e08f3309d5b942c1979a6f4a58a8c59d5fa299728e9c2fcd1a759ec870863b1fd38653670240cd420dad2ad9330c71f36608a6a1c912 + languageName: node + linkType: hard + "signal-exit@npm:^4.0.1": version: 4.1.0 resolution: "signal-exit@npm:4.1.0" @@ -10399,6 +11092,24 @@ __metadata: languageName: node linkType: hard +"simple-concat@npm:^1.0.0": + version: 1.0.1 + resolution: "simple-concat@npm:1.0.1" + checksum: 10c0/62f7508e674414008910b5397c1811941d457dfa0db4fd5aa7fa0409eb02c3609608dfcd7508cace75b3a0bf67a2a77990711e32cd213d2c76f4fd12ee86d776 + languageName: node + linkType: hard + +"simple-get@npm:^4.0.0": + version: 4.0.1 + resolution: "simple-get@npm:4.0.1" + dependencies: + decompress-response: "npm:^6.0.0" + once: "npm:^1.3.1" + simple-concat: "npm:^1.0.0" + checksum: 10c0/b0649a581dbca741babb960423248899203165769747142033479a7dc5e77d7b0fced0253c731cd57cf21e31e4d77c9157c3069f4448d558ebc96cf9e1eebcf0 + languageName: node + linkType: hard + "sirv@npm:^3.0.2": version: 3.0.2 resolution: "sirv@npm:3.0.2" @@ -10469,6 +11180,20 @@ __metadata: languageName: node linkType: hard +"spawn-wrap@npm:^2.0.0": + version: 2.0.0 + resolution: "spawn-wrap@npm:2.0.0" + dependencies: + foreground-child: "npm:^2.0.0" + is-windows: "npm:^1.0.2" + make-dir: "npm:^3.0.0" + rimraf: "npm:^3.0.0" + signal-exit: "npm:^3.0.2" + which: "npm:^2.0.1" + checksum: 10c0/0d30001391eedbd588722be74506d3e60582557e754fe3deb3f84f2c84ddca0d72d8132f16502cf312bacb8952cc7abe833d6f45b4e80c8baea3fa56c5554d3d + languageName: node + linkType: hard + "spdx-correct@npm:^3.0.0": version: 3.2.0 resolution: "spdx-correct@npm:3.2.0" @@ -10542,6 +11267,13 @@ __metadata: languageName: node linkType: hard +"sprintf-js@npm:~1.0.2": + version: 1.0.3 + resolution: "sprintf-js@npm:1.0.3" + checksum: 10c0/ecadcfe4c771890140da5023d43e190b7566d9cf8b2d238600f31bec0fc653f328da4450eb04bd59a431771a8e9cc0e118f0aa3974b683a4981b4e07abc2a5bb + languageName: node + linkType: hard + "ssri@npm:^10.0.0": version: 10.0.5 resolution: "ssri@npm:10.0.5" @@ -10810,6 +11542,13 @@ __metadata: languageName: node linkType: hard +"strip-bom@npm:^4.0.0": + version: 4.0.0 + resolution: "strip-bom@npm:4.0.0" + checksum: 10c0/26abad1172d6bc48985ab9a5f96c21e440f6e7e476686de49be813b5a59b3566dccb5c525b831ec54fe348283b47f3ffb8e080bc3f965fde12e84df23f6bb7ef + languageName: node + linkType: hard + "strip-indent@npm:^3.0.0": version: 3.0.0 resolution: "strip-indent@npm:3.0.0" @@ -10835,6 +11574,13 @@ __metadata: languageName: node linkType: hard +"strip-json-comments@npm:~2.0.1": + version: 2.0.1 + resolution: "strip-json-comments@npm:2.0.1" + checksum: 10c0/b509231cbdee45064ff4f9fd73609e2bcc4e84a4d508e9dd0f31f70356473fde18abfb5838c17d56fb236f5a06b102ef115438de0600b749e818a35fbbc48c43 + languageName: node + linkType: hard + "superjson@npm:^2.2.2": version: 2.2.6 resolution: "superjson@npm:2.2.6" @@ -10900,6 +11646,31 @@ __metadata: languageName: node linkType: hard +"tar-fs@npm:^2.0.0": + version: 2.1.4 + resolution: "tar-fs@npm:2.1.4" + dependencies: + chownr: "npm:^1.1.1" + mkdirp-classic: "npm:^0.5.2" + pump: "npm:^3.0.0" + tar-stream: "npm:^2.1.4" + checksum: 10c0/decb25acdc6839182c06ec83cba6136205bda1db984e120c8ffd0d80182bc5baa1d916f9b6c5c663ea3f9975b4dd49e3c6bb7b1707cbcdaba4e76042f43ec84c + languageName: node + linkType: hard + +"tar-stream@npm:^2.1.4": + version: 2.2.0 + resolution: "tar-stream@npm:2.2.0" + dependencies: + bl: "npm:^4.0.3" + end-of-stream: "npm:^1.4.1" + fs-constants: "npm:^1.0.0" + inherits: "npm:^2.0.3" + readable-stream: "npm:^3.1.1" + checksum: 10c0/2f4c910b3ee7196502e1ff015a7ba321ec6ea837667220d7bcb8d0852d51cb04b87f7ae471008a6fb8f5b1a1b5078f62f3a82d30c706f20ada1238ac797e7692 + languageName: node + linkType: hard + "tar@npm:^6.1.11, tar@npm:^6.1.2": version: 6.2.0 resolution: "tar@npm:6.2.0" @@ -10914,6 +11685,17 @@ __metadata: languageName: node linkType: hard +"test-exclude@npm:^6.0.0": + version: 6.0.0 + resolution: "test-exclude@npm:6.0.0" + dependencies: + "@istanbuljs/schema": "npm:^0.1.2" + glob: "npm:^7.1.4" + minimatch: "npm:^3.0.4" + checksum: 10c0/019d33d81adff3f9f1bfcff18125fb2d3c65564f437d9be539270ee74b994986abb8260c7c2ce90e8f30162178b09dbbce33c6389273afac4f36069c48521f57 + languageName: node + linkType: hard + "text-extensions@npm:^1.0.0": version: 1.9.0 resolution: "text-extensions@npm:1.9.0" @@ -11161,6 +11943,15 @@ __metadata: languageName: node linkType: hard +"tunnel-agent@npm:^0.6.0": + version: 0.6.0 + resolution: "tunnel-agent@npm:0.6.0" + dependencies: + safe-buffer: "npm:^5.0.1" + checksum: 10c0/4c7a1b813e7beae66fdbf567a65ec6d46313643753d0beefb3c7973d66fcec3a1e7f39759f0a0b4465883499c6dc8b0750ab8b287399af2e583823e40410a17a + languageName: node + linkType: hard + "type-check@npm:^0.4.0, type-check@npm:~0.4.0": version: 0.4.0 resolution: "type-check@npm:0.4.0" @@ -11184,7 +11975,7 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^0.8.1": +"type-fest@npm:^0.8.0, type-fest@npm:^0.8.1": version: 0.8.1 resolution: "type-fest@npm:0.8.1" checksum: 10c0/dffbb99329da2aa840f506d376c863bd55f5636f4741ad6e65e82f5ce47e6914108f44f340a0b74009b0cb5d09d6752ae83203e53e98b1192cf80ecee5651636 @@ -11317,6 +12108,15 @@ __metadata: languageName: node linkType: hard +"typedarray-to-buffer@npm:^3.1.5": + version: 3.1.5 + resolution: "typedarray-to-buffer@npm:3.1.5" + dependencies: + is-typedarray: "npm:^1.0.0" + checksum: 10c0/4ac5b7a93d604edabf3ac58d3a2f7e07487e9f6e98195a080e81dbffdc4127817f470f219d794a843b87052cedef102b53ac9b539855380b8c2172054b7d5027 + languageName: node + linkType: hard + "typedarray@npm:^0.0.6": version: 0.0.6 resolution: "typedarray@npm:0.0.6" @@ -11542,6 +12342,15 @@ __metadata: languageName: node linkType: hard +"uuid@npm:^8.3.2": + version: 8.3.2 + resolution: "uuid@npm:8.3.2" + bin: + uuid: dist/bin/uuid + checksum: 10c0/bcbb807a917d374a49f475fae2e87fdca7da5e5530820ef53f65ba1d12131bd81a92ecf259cc7ce317cbe0f289e7d79fdfebcef9bfa3087c8c8a2fa304c9be54 + languageName: node + linkType: hard + "v8-compile-cache-lib@npm:^3.0.1": version: 3.0.1 resolution: "v8-compile-cache-lib@npm:3.0.1" @@ -12172,6 +12981,13 @@ __metadata: languageName: node linkType: hard +"which-module@npm:^2.0.0": + version: 2.0.1 + resolution: "which-module@npm:2.0.1" + checksum: 10c0/087038e7992649eaffa6c7a4f3158d5b53b14cf5b6c1f0e043dccfacb1ba179d12f17545d5b85ebd94a42ce280a6fe65d0cbcab70f4fc6daad1dfae85e0e6a3e + languageName: node + linkType: hard + "which-typed-array@npm:^1.1.13, which-typed-array@npm:^1.1.14, which-typed-array@npm:^1.1.15": version: 1.1.15 resolution: "which-typed-array@npm:1.1.15" @@ -12264,6 +13080,17 @@ __metadata: languageName: node linkType: hard +"wrap-ansi@npm:^6.2.0": + version: 6.2.0 + resolution: "wrap-ansi@npm:6.2.0" + dependencies: + ansi-styles: "npm:^4.0.0" + string-width: "npm:^4.1.0" + strip-ansi: "npm:^6.0.0" + checksum: 10c0/baad244e6e33335ea24e86e51868fe6823626e3a3c88d9a6674642afff1d34d9a154c917e74af8d845fd25d170c4ea9cf69a47133c3f3656e1252b3d462d9f6c + languageName: node + linkType: hard + "wrap-ansi@npm:^8.1.0": version: 8.1.0 resolution: "wrap-ansi@npm:8.1.0" @@ -12275,6 +13102,25 @@ __metadata: languageName: node linkType: hard +"wrappy@npm:1": + version: 1.0.2 + resolution: "wrappy@npm:1.0.2" + checksum: 10c0/56fece1a4018c6a6c8e28fbc88c87e0fbf4ea8fd64fc6c63b18f4acc4bd13e0ad2515189786dd2c30d3eec9663d70f4ecf699330002f8ccb547e4a18231fc9f0 + languageName: node + linkType: hard + +"write-file-atomic@npm:^3.0.0": + version: 3.0.3 + resolution: "write-file-atomic@npm:3.0.3" + dependencies: + imurmurhash: "npm:^0.1.4" + is-typedarray: "npm:^1.0.0" + signal-exit: "npm:^3.0.2" + typedarray-to-buffer: "npm:^3.1.5" + checksum: 10c0/7fb67affd811c7a1221bed0c905c26e28f0041e138fb19ccf02db57a0ef93ea69220959af3906b920f9b0411d1914474cdd90b93a96e5cd9e8368d9777caac0e + languageName: node + linkType: hard + "ws@npm:^8.18.0": version: 8.18.0 resolution: "ws@npm:8.18.0" @@ -12290,6 +13136,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:^8.18.3": + version: 8.19.0 + resolution: "ws@npm:8.19.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 10c0/4741d9b9bc3f9c791880882414f96e36b8b254e34d4b503279d6400d9a4b87a033834856dbdd94ee4b637944df17ea8afc4bce0ff4a1560d2166be8855da5b04 + languageName: node + linkType: hard + "wsl-utils@npm:^0.1.0": version: 0.1.0 resolution: "wsl-utils@npm:0.1.0" @@ -12327,6 +13188,13 @@ __metadata: languageName: node linkType: hard +"y18n@npm:^4.0.0": + version: 4.0.3 + resolution: "y18n@npm:4.0.3" + checksum: 10c0/308a2efd7cc296ab2c0f3b9284fd4827be01cfeb647b3ba18230e3a416eb1bc887ac050de9f8c4fd9e7856b2e8246e05d190b53c96c5ad8d8cb56dffb6f81024 + languageName: node + linkType: hard + "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8" @@ -12357,6 +13225,16 @@ __metadata: languageName: node linkType: hard +"yargs-parser@npm:^18.1.2": + version: 18.1.3 + resolution: "yargs-parser@npm:18.1.3" + dependencies: + camelcase: "npm:^5.0.0" + decamelize: "npm:^1.2.0" + checksum: 10c0/25df918833592a83f52e7e4f91ba7d7bfaa2b891ebf7fe901923c2ee797534f23a176913ff6ff7ebbc1cc1725a044cc6a6539fed8bfd4e13b5b16376875f9499 + languageName: node + linkType: hard + "yargs-parser@npm:^20.2.2, yargs-parser@npm:^20.2.3": version: 20.2.9 resolution: "yargs-parser@npm:20.2.9" @@ -12371,6 +13249,25 @@ __metadata: languageName: node linkType: hard +"yargs@npm:^15.0.2": + version: 15.4.1 + resolution: "yargs@npm:15.4.1" + dependencies: + cliui: "npm:^6.0.0" + decamelize: "npm:^1.2.0" + find-up: "npm:^4.1.0" + get-caller-file: "npm:^2.0.1" + require-directory: "npm:^2.1.1" + require-main-filename: "npm:^2.0.0" + set-blocking: "npm:^2.0.0" + string-width: "npm:^4.2.0" + which-module: "npm:^2.0.0" + y18n: "npm:^4.0.0" + yargs-parser: "npm:^18.1.2" + checksum: 10c0/f1ca680c974333a5822732825cca7e95306c5a1e7750eb7b973ce6dc4f97a6b0a8837203c8b194f461969bfe1fb1176d1d423036635285f6010b392fa498ab2d + languageName: node + linkType: hard + "yargs@npm:^16.0.0, yargs@npm:^16.2.0": version: 16.2.0 resolution: "yargs@npm:16.2.0"